From 8ebd2a57d6256f85ba0970a82c181aa7d94f8d0a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Oct 2012 15:09:06 -0700 Subject: [PATCH 01/42] Simplify ensure_canon_entry_valid by splitting out the _get codepath. --- source3/smbd/posix_acls.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 3 deletions(-) diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 5ce3bf3..c9ae440 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1342,6 +1342,89 @@ static bool uid_entry_in_group(connection_struct *conn, canon_ace *uid_ace, cano } /**************************************************************************** + A well formed POSIX file or default ACL has at least 3 entries, a + SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ. + In addition, the owner must always have at least read access. + When using this call on get_acl, the pst struct is valid and contains + the mode of the file. +****************************************************************************/ + +static bool ensure_canon_entry_valid_on_get(connection_struct *conn, + canon_ace **pp_ace, + const struct dom_sid *pfile_owner_sid, + const struct dom_sid *pfile_grp_sid, + const SMB_STRUCT_STAT *pst) +{ + canon_ace *pace; + bool got_user = false; + bool got_group = false; + bool got_other = false; + + for (pace = *pp_ace; pace; pace = pace->next) { + if (pace->type == SMB_ACL_USER_OBJ) { + got_user = true; + } else if (pace->type == SMB_ACL_GROUP_OBJ) { + got_group = true; + } else if (pace->type == SMB_ACL_OTHER) { + got_other = true; + } + } + + if (!got_user) { + if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) { + DEBUG(0,("malloc fail.\n")); + return false; + } + + ZERO_STRUCTP(pace); + pace->type = SMB_ACL_USER_OBJ; + pace->owner_type = UID_ACE; + pace->unix_ug.type = ID_TYPE_UID; + pace->unix_ug.id = pst->st_ex_uid; + pace->trustee = *pfile_owner_sid; + pace->attr = ALLOW_ACE; + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); + DLIST_ADD(*pp_ace, pace); + } + + if (!got_group) { + if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) { + DEBUG(0,("malloc fail.\n")); + return false; + } + + ZERO_STRUCTP(pace); + pace->type = SMB_ACL_GROUP_OBJ; + pace->owner_type = GID_ACE; + pace->unix_ug.type = ID_TYPE_GID; + pace->unix_ug.id = pst->st_ex_gid; + pace->trustee = *pfile_grp_sid; + pace->attr = ALLOW_ACE; + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRGRP, S_IWGRP, S_IXGRP); + DLIST_ADD(*pp_ace, pace); + } + + if (!got_other) { + if ((pace = talloc(talloc_tos(), canon_ace)) == NULL) { + DEBUG(0,("malloc fail.\n")); + return false; + } + + ZERO_STRUCTP(pace); + pace->type = SMB_ACL_OTHER; + pace->owner_type = WORLD_ACE; + pace->unix_ug.type = ID_TYPE_NOT_SPECIFIED; + pace->unix_ug.id = -1; + pace->trustee = global_sid_World; + pace->attr = ALLOW_ACE; + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IROTH, S_IWOTH, S_IXOTH); + DLIST_ADD(*pp_ace, pace); + } + + return true; +} + +/**************************************************************************** A well formed POSIX file or default ACL has at least 3 entries, a SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ. In addition, the owner must always have at least read access. @@ -2755,9 +2838,9 @@ static canon_ace *canonicalise_acl(struct connection_struct *conn, * This next call will ensure we have at least a user/group/world set. */ - if (!ensure_canon_entry_valid(conn, &l_head, is_default_acl, conn->params, - S_ISDIR(psbuf->st_ex_mode), powner, pgroup, - psbuf, False)) + if (!ensure_canon_entry_valid_on_get(conn, &l_head, + powner, pgroup, + psbuf)) goto fail; /* -- 1.7.11.7 From 063f7154eed817232077a8f5347170f055aeb6c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Oct 2012 15:51:19 -0700 Subject: [PATCH 02/42] We should never just assign an st_mode to an ace->perms field, theoretically they are different so should go through a mapping function. Ensure this is so. Practically this does not matter, as for user permissions the mapping function is an identity, and the extra bits we may add are ignored anyway, but this makes the intent clear. Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Sat Oct 6 03:04:14 CEST 2012 on sn-devel-104 --- source3/smbd/posix_acls.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index c9ae440..fe0f23a 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1508,9 +1508,9 @@ static bool ensure_canon_entry_valid(connection_struct *conn, pace->unix_ug.id = pst->st_ex_uid; pace->trustee = *pfile_owner_sid; pace->attr = ALLOW_ACE; - /* Start with existing permissions, principle of least + /* Start with existing user permissions, principle of least surprises for the user. */ - pace->perms = pst->st_ex_mode; + pace->perms = unix_perms_to_acl_perms(pst->st_ex_mode, S_IRUSR, S_IWUSR, S_IXUSR); if (setting_acl) { /* See if the owning user is in any of the other groups in -- 1.7.11.7 From 49133e42f115b3a7a37dead60be9086bd2559edf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Oct 2012 12:45:30 -0700 Subject: [PATCH 03/42] Move setting of psd->dacl->revision and protect against null SD's. --- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 107e459..2b03f09 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2100,6 +2100,10 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } + if (psd && psd->dacl) { + psd->dacl->revision = NT4_ACL_REVISION; + } + sd_size = ndr_size_security_descriptor(psd, 0); sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf); @@ -2113,8 +2117,6 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, *r->out.sd_buf = sd_buf; - psd->dacl->revision = NT4_ACL_REVISION; - close_file(NULL, fsp, NORMAL_CLOSE); vfs_ChDir(conn, oldcwd); SMB_VFS_DISCONNECT(conn); -- 1.7.11.7 From f2ee984da84579134d165bbe6b3c060aacd6c4b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Oct 2012 12:46:57 -0700 Subject: [PATCH 04/42] Make sure the returned sd is on the right context, and if not it's always freed. Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Oct 9 23:35:50 CEST 2012 on sn-devel-104 --- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 2b03f09..696c7bf 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2113,7 +2113,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, } sd_buf->sd_size = sd_size; - sd_buf->sd = psd; + sd_buf->sd = talloc_move(p->mem_ctx, &psd); *r->out.sd_buf = sd_buf; @@ -2140,6 +2140,8 @@ error_exit: } done: + + TALLOC_FREE(psd); TALLOC_FREE(smb_fname); return werr; -- 1.7.11.7 From 4b42e2bd1a8e17e85babac7c545379de8ddc5909 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 10:18:32 +1100 Subject: [PATCH 05/42] smbd: Add mem_ctx to sys_acl_init() and all callers This changes from allocation on NULL to allocation on the supplied memory context. Currently that supplied context is talloc_tos() at the the final consumer of the ACL. Andrew Bartlett --- examples/VFS/skel_opaque.c | 9 +++++-- examples/VFS/skel_transparent.c | 13 ++++++---- source3/include/smb_acls.h | 8 ++++--- source3/include/vfs.h | 15 ++++++++---- source3/include/vfs_macros.h | 18 +++++++------- source3/lib/sysacls.c | 12 +++++----- source3/modules/vfs_aixacl2.c | 9 +++---- source3/modules/vfs_aixacl_util.c | 4 ++-- source3/modules/vfs_aixacl_util.h | 2 +- source3/modules/vfs_cap.c | 6 +++-- source3/modules/vfs_catia.c | 5 ++-- source3/modules/vfs_default.c | 13 ++++++---- source3/modules/vfs_fake_acls.c | 18 ++++++++------ source3/modules/vfs_full_audit.c | 9 +++---- source3/modules/vfs_gpfs.c | 24 +++++++++++-------- source3/modules/vfs_hpuxacl.c | 17 ++++++++------ source3/modules/vfs_media_harmony.c | 9 +++---- source3/modules/vfs_posixacl.c | 15 ++++++------ source3/modules/vfs_posixacl.h | 6 +++-- source3/modules/vfs_solarisacl.c | 12 +++++----- source3/modules/vfs_time_audit.c | 10 ++++---- source3/modules/vfs_tru64acl.c | 18 ++++++++------ source3/smbd/posix_acls.c | 47 +++++++++++++++++++++++++------------ source3/smbd/pysmbd.c | 40 +++++++++++++++---------------- source3/smbd/trans2.c | 12 ++++++---- source3/smbd/vfs.c | 10 ++++---- source3/torture/cmd_vfs.c | 4 ++-- 27 files changed, 219 insertions(+), 146 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index a786a23..3b91848 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -574,13 +574,18 @@ static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t return -1; } -static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, + const char *path_p, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { errno = ENOSYS; return (SMB_ACL_T)NULL; } -static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx) { errno = ENOSYS; return (SMB_ACL_T)NULL; diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index 02a994c..a00b0e1 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -689,14 +689,19 @@ static int skel_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode_t return SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode); } -static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +static SMB_ACL_T skel_sys_acl_get_file(vfs_handle_struct *handle, + const char *path_p, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { - return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); + return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx); } -static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +static SMB_ACL_T skel_sys_acl_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx) { - return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); + return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx); } static int skel_sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type, diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h index dbcf3b7..3ac23db 100644 --- a/source3/include/smb_acls.h +++ b/source3/include/smb_acls.h @@ -44,7 +44,7 @@ int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d); int sys_acl_add_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm); int sys_acl_get_perm(SMB_ACL_PERMSET_T permset_d, SMB_ACL_PERM_T perm); char *sys_acl_to_text(const struct smb_acl_t *acl_d, ssize_t *len_p); -SMB_ACL_T sys_acl_init(void); +SMB_ACL_T sys_acl_init(TALLOC_CTX *mem_ctx); int sys_acl_create_entry(SMB_ACL_T *acl_p, SMB_ACL_ENTRY_T *entry_p); int sys_acl_set_tag_type(SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T tag_type); int sys_acl_set_qualifier(SMB_ACL_ENTRY_T entry_d, void *qual_p); @@ -52,8 +52,10 @@ int sys_acl_set_permset(SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T permset_d); int sys_acl_free_text(char *text); int sys_acl_valid(SMB_ACL_T acl_d); SMB_ACL_T sys_acl_get_file(struct vfs_handle_struct *handle, - const char *path_p, SMB_ACL_TYPE_T type); -SMB_ACL_T sys_acl_get_fd(struct vfs_handle_struct *handle, struct files_struct *fsp); + const char *path_p, SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx); +SMB_ACL_T sys_acl_get_fd(struct vfs_handle_struct *handle, struct files_struct *fsp, + TALLOC_CTX *mem_ctx); int sys_acl_set_file(struct vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T type, SMB_ACL_T acl_d); int sys_acl_set_fd(struct vfs_handle_struct *handle, struct files_struct *fsp, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index c83e7ed..4ba11be 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -692,8 +692,13 @@ struct vfs_fn_pointers { int (*chmod_acl_fn)(struct vfs_handle_struct *handle, const char *name, mode_t mode); int (*fchmod_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode); - 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); + SMB_ACL_T (*sys_acl_get_file_fn)(struct vfs_handle_struct *handle, + const char *path_p, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx); + SMB_ACL_T (*sys_acl_get_fd_fn)(struct vfs_handle_struct *handle, + struct files_struct *fsp, + TALLOC_CTX *mem_ctx); 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); @@ -1094,9 +1099,11 @@ int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, mode_t mode); SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx); SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle, - struct files_struct *fsp); + struct files_struct *fsp, + TALLOC_CTX *mem_ctx); int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index 4eca1b0..f1bc8ff 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -429,15 +429,15 @@ #define SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode) \ smb_vfs_call_fchmod_acl((handle)->next, (fsp), (mode)) -#define SMB_VFS_SYS_ACL_GET_FILE(conn, path_p, type) \ - smb_vfs_call_sys_acl_get_file((conn)->vfs_handles, (path_p), (type)) -#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type) \ - smb_vfs_call_sys_acl_get_file((handle)->next, (path_p), (type)) - -#define SMB_VFS_SYS_ACL_GET_FD(fsp) \ - smb_vfs_call_sys_acl_get_fd((fsp)->conn->vfs_handles, (fsp)) -#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_GET_FILE(conn, path_p, type, mem_ctx) \ + smb_vfs_call_sys_acl_get_file((conn)->vfs_handles, (path_p), (type), (mem_ctx)) +#define SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx) \ + smb_vfs_call_sys_acl_get_file((handle)->next, (path_p), (type), (mem_ctx)) + +#define SMB_VFS_SYS_ACL_GET_FD(fsp, mem_ctx) \ + smb_vfs_call_sys_acl_get_fd((fsp)->conn->vfs_handles, (fsp), (mem_ctx)) +#define SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx) \ + smb_vfs_call_sys_acl_get_fd((handle)->next, (fsp), (mem_ctx)) #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)) diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c index a5430d6..2245491 100644 --- a/source3/lib/sysacls.c +++ b/source3/lib/sysacls.c @@ -249,11 +249,11 @@ char *sys_acl_to_text(const struct smb_acl_t *acl_d, ssize_t *len_p) return text; } -SMB_ACL_T sys_acl_init(void) +SMB_ACL_T sys_acl_init(TALLOC_CTX *mem_ctx) { SMB_ACL_T a; - if ((a = talloc(NULL, struct smb_acl_t)) == NULL) { + if ((a = talloc(mem_ctx, struct smb_acl_t)) == NULL) { errno = ENOMEM; return NULL; } @@ -364,14 +364,14 @@ int sys_acl_valid(SMB_ACL_T acl_d) #if defined(HAVE_POSIX_ACLS) SMB_ACL_T sys_acl_get_file(vfs_handle_struct *handle, - const char *path_p, SMB_ACL_TYPE_T type) + const char *path_p, SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx) { - return posixacl_sys_acl_get_file(handle, path_p, type); + return posixacl_sys_acl_get_file(handle, path_p, type, mem_ctx); } -SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +SMB_ACL_T sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx) { - return posixacl_sys_acl_get_fd(handle, fsp); + return posixacl_sys_acl_get_fd(handle, fsp, mem_ctx); } int sys_acl_set_file(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index dd705ea..0d754d7 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -200,7 +200,7 @@ static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle, pacl); } -static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type) +static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type, TALLOC_CTX *mem_ctx) { aixc_acl_t *pacl; AIXJFS2_ACL_T *acl; @@ -222,7 +222,7 @@ static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type) DEBUG(10, ("len: %d, mode: %d\n", pacl->acl_len, pacl->acl_mode)); - result = aixacl_to_smbacl(pacl); + result = aixacl_to_smbacl(pacl, mem_ctx); if (result == NULL) { goto done; } @@ -236,7 +236,8 @@ static SMB_ACL_T aixjfs2_get_posix_acl(const char *path, acl_type_t type) SMB_ACL_T aixjfs2_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { acl_type_t aixjfs2_type; @@ -252,7 +253,7 @@ SMB_ACL_T aixjfs2_sys_acl_get_file(vfs_handle_struct *handle, smb_panic("exiting"); } - return aixjfs2_get_posix_acl(path_p, aixjfs2_type); + return aixjfs2_get_posix_acl(path_p, aixjfs2_type, mem_ctx); } SMB_ACL_T aixjfs2_sys_acl_get_fd(vfs_handle_struct *handle, diff --git a/source3/modules/vfs_aixacl_util.c b/source3/modules/vfs_aixacl_util.c index 82e8bd1..1194d27 100644 --- a/source3/modules/vfs_aixacl_util.c +++ b/source3/modules/vfs_aixacl_util.c @@ -22,12 +22,12 @@ #include "smbd/smbd.h" #include "vfs_aixacl_util.h" -SMB_ACL_T aixacl_to_smbacl(struct acl *file_acl) +SMB_ACL_T aixacl_to_smbacl(struct acl *file_acl, TALLOC_CTX *mem_ctx) { struct acl_entry *acl_entry; struct ace_id *idp; - struct smb_acl_t *result = sys_acl_init(); + struct smb_acl_t *result = sys_acl_init(mem_ctx); struct smb_acl_entry *ace; int i; diff --git a/source3/modules/vfs_aixacl_util.h b/source3/modules/vfs_aixacl_util.h index 2447252..e283a3d 100644 --- a/source3/modules/vfs_aixacl_util.h +++ b/source3/modules/vfs_aixacl_util.h @@ -17,6 +17,6 @@ along with this program. If not, see . */ -SMB_ACL_T aixacl_to_smbacl( struct acl *file_acl); +SMB_ACL_T aixacl_to_smbacl( struct acl *file_acl, TALLOC_CTX *mem_ctx); struct acl *aixacl_smb_to_aixacl(SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index 2454e12..f2f8d71 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -409,7 +409,9 @@ static int cap_chmod_acl(vfs_handle_struct *handle, const char *path, mode_t mod return SMB_VFS_NEXT_CHMOD_ACL(handle, cappath, mode); } -static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T type) +static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, + const char *path, SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { char *cappath = capencode(talloc_tos(), path); @@ -417,7 +419,7 @@ static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle, const char *pat errno = ENOMEM; return (SMB_ACL_T)NULL; } - return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath, type); + return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cappath, type, mem_ctx); } static int cap_sys_acl_set_file(vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index 821a755..a2bef44 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -745,7 +745,8 @@ catia_chmod_acl(vfs_handle_struct *handle, static SMB_ACL_T catia_sys_acl_get_file(vfs_handle_struct *handle, const char *path, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { char *mapped_name = NULL; NTSTATUS status; @@ -758,7 +759,7 @@ catia_sys_acl_get_file(vfs_handle_struct *handle, return NULL; } - ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_name, type); + ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, mapped_name, type, mem_ctx); TALLOC_FREE(mapped_name); return ret; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index ebfa607..a03a4f8 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2128,14 +2128,19 @@ static int vfswrap_fchmod_acl(vfs_handle_struct *handle, files_struct *fsp, mode #endif } -static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, SMB_ACL_TYPE_T type) +static SMB_ACL_T vfswrap_sys_acl_get_file(vfs_handle_struct *handle, + const char *path_p, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { - return sys_acl_get_file(handle, path_p, type); + return sys_acl_get_file(handle, path_p, type, mem_ctx); } -static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, files_struct *fsp) +static SMB_ACL_T vfswrap_sys_acl_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx) { - return sys_acl_get_fd(handle, fsp); + return sys_acl_get_fd(handle, fsp, mem_ctx); } static int vfswrap_sys_acl_set_file(vfs_handle_struct *handle, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) diff --git a/source3/modules/vfs_fake_acls.c b/source3/modules/vfs_fake_acls.c index 258cb19..ea3db23 100644 --- a/source3/modules/vfs_fake_acls.c +++ b/source3/modules/vfs_fake_acls.c @@ -189,11 +189,10 @@ static int fake_acls_fstat(vfs_handle_struct *handle, files_struct *fsp, SMB_STR return ret; } -static SMB_ACL_T fake_acls_blob2acl(DATA_BLOB *blob) +static SMB_ACL_T fake_acls_blob2acl(DATA_BLOB *blob, TALLOC_CTX *mem_ctx) { enum ndr_err_code ndr_err; - /* For now, ACLs are allocated on NULL */ - struct smb_acl_t *acl = talloc(NULL, struct smb_acl_t); + struct smb_acl_t *acl = talloc(mem_ctx, struct smb_acl_t); if (!acl) { errno = ENOMEM; return NULL; @@ -226,7 +225,10 @@ static DATA_BLOB fake_acls_acl2blob(TALLOC_CTX *mem_ctx, SMB_ACL_T acl) return blob; } -static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle, const char *path, SMB_ACL_TYPE_T type) +static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle, + const char *path, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { DATA_BLOB blob = data_blob_null; ssize_t length; @@ -258,13 +260,15 @@ static SMB_ACL_T fake_acls_sys_acl_get_file(struct vfs_handle_struct *handle, co return NULL; } if (length != -1) { - acl = fake_acls_blob2acl(&blob); + acl = fake_acls_blob2acl(&blob, mem_ctx); } TALLOC_FREE(frame); return acl; } -static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle, files_struct *fsp) +static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle, + files_struct *fsp, + TALLOC_CTX *mem_ctx) { DATA_BLOB blob = data_blob_null; ssize_t length; @@ -288,7 +292,7 @@ static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle, file return NULL; } if (length != -1) { - acl = fake_acls_blob2acl(&blob); + acl = fake_acls_blob2acl(&blob, mem_ctx); } TALLOC_FREE(frame); return acl; diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index 6050c55..e56c4a8 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1803,11 +1803,12 @@ static int smb_full_audit_fchmod_acl(vfs_handle_struct *handle, files_struct *fs static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result; - result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); + result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx); do_log(SMB_VFS_OP_SYS_ACL_GET_FILE, (result != NULL), handle, "%s", path_p); @@ -1816,11 +1817,11 @@ static SMB_ACL_T smb_full_audit_sys_acl_get_file(vfs_handle_struct *handle, } static SMB_ACL_T smb_full_audit_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, TALLOC_CTX *mem_ctx) { SMB_ACL_T result; - result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); + result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx); do_log(SMB_VFS_OP_SYS_ACL_GET_FD, (result != NULL), handle, "%s", fsp_str_do_log(fsp)); diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 8959fe6..412c48c 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -549,12 +549,12 @@ static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl) +static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl, TALLOC_CTX *mem_ctx) { SMB_ACL_T result; gpfs_aclCount_t i; - result = sys_acl_init(); + result = sys_acl_init(mem_ctx); if (result == NULL) { errno = ENOMEM; return NULL; @@ -614,7 +614,8 @@ static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl) return result; } -static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type) +static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type, + TALLOC_CTX *mem_ctx) { struct gpfs_acl *pacl; SMB_ACL_T result = NULL; @@ -641,7 +642,7 @@ static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type) pacl->acl_len, pacl->acl_level, pacl->acl_version, pacl->acl_nace)); - result = gpfs2smb_acl(pacl); + result = gpfs2smb_acl(pacl, mem_ctx); if (result != NULL) { errno = 0; } @@ -656,7 +657,8 @@ static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type) static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { gpfs_aclType_t gpfs_type; struct gpfs_config_data *config; @@ -666,7 +668,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, return NULL); if (!config->acl) { - return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); + return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, + type, mem_ctx); } switch(type) { @@ -681,11 +684,12 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, smb_panic("exiting"); } - return gpfsacl_get_posix_acl(path_p, gpfs_type); + return gpfsacl_get_posix_acl(path_p, gpfs_type, mem_ctx); } static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, + TALLOC_CTX *mem_ctx) { struct gpfs_config_data *config; @@ -694,11 +698,11 @@ static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, return NULL); if (!config->acl) { - return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); + return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx); } return gpfsacl_get_posix_acl(fsp->fsp_name->base_name, - GPFS_ACL_TYPE_ACCESS); + GPFS_ACL_TYPE_ACCESS, mem_ctx); } static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl, diff --git a/source3/modules/vfs_hpuxacl.c b/source3/modules/vfs_hpuxacl.c index 884cc5c..6a0fb9b 100644 --- a/source3/modules/vfs_hpuxacl.c +++ b/source3/modules/vfs_hpuxacl.c @@ -112,7 +112,7 @@ static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl, HPUX_ACL_T *solariacl, int *count, SMB_ACL_TYPE_T type); static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpuxacl, int count, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx); static HPUX_ACL_TAG_T smb_tag_to_hpux_tag(SMB_ACL_TAG_T smb_tag); static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag); static bool hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count, @@ -140,7 +140,8 @@ static bool hpux_aclsort_call_present(void); SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result = NULL; int count; @@ -168,7 +169,7 @@ SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle, if (!hpux_acl_get_file(path_p, &hpux_acl, &count)) { goto done; } - result = hpux_acl_to_smb_acl(hpux_acl, count, type); + result = hpux_acl_to_smb_acl(hpux_acl, count, type, mem_ctx); if (result == NULL) { DEBUG(10, ("conversion hpux_acl -> smb_acl failed (%s).\n", strerror(errno))); @@ -186,7 +187,8 @@ SMB_ACL_T hpuxacl_sys_acl_get_file(vfs_handle_struct *handle, * get the access ACL of a file referred to by a fd */ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, + TALLOC_CTX *mem_ctx) { /* * HPUX doesn't have the facl call. Fake it using the path.... JRA. @@ -200,7 +202,8 @@ SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle, return hpuxacl_sys_acl_get_file(handle, fsp->fsp_name->base_name, - SMB_ACL_TYPE_ACCESS); + SMB_ACL_TYPE_ACCESS, + mem_ctx); } @@ -490,12 +493,12 @@ static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl, * soaris acl to the SMB_ACL format. */ static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx) { SMB_ACL_T result; int i; - if ((result = sys_acl_init()) == NULL) { + if ((result = sys_acl_init(mem_ctx)) == NULL) { DEBUG(10, ("error allocating memory for SMB_ACL\n")); goto fail; } diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index 647db7c..a10eb5e 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -2085,8 +2085,9 @@ out: * Failure: set errno, return NULL */ static SMB_ACL_T mh_sys_acl_get_file(vfs_handle_struct *handle, - const char *path_p, - SMB_ACL_TYPE_T type) + const char *path_p, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T ret; char *clientPath; @@ -2095,7 +2096,7 @@ static SMB_ACL_T mh_sys_acl_get_file(vfs_handle_struct *handle, DEBUG(MH_INFO_DEBUG, ("Entering mh_sys_acl_get_file\n")); if (!is_in_media_files(path_p)) { - ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); + ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx); goto out; } @@ -2110,7 +2111,7 @@ static SMB_ACL_T mh_sys_acl_get_file(vfs_handle_struct *handle, goto err; } - ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, clientPath, type); + ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, clientPath, type, mem_ctx); err: TALLOC_FREE(clientPath); out: diff --git a/source3/modules/vfs_posixacl.c b/source3/modules/vfs_posixacl.c index 50487ff..1714b13 100644 --- a/source3/modules/vfs_posixacl.c +++ b/source3/modules/vfs_posixacl.c @@ -26,7 +26,7 @@ static bool smb_ace_to_internal(acl_entry_t posix_ace, struct smb_acl_entry *ace); -static struct smb_acl_t *smb_acl_to_internal(acl_t acl); +static struct smb_acl_t *smb_acl_to_internal(acl_t acl, TALLOC_CTX *mem_ctx); static int smb_acl_set_mode(acl_entry_t entry, SMB_ACL_PERM_T perm); static acl_t smb_acl_to_posix(const struct smb_acl_t *acl); @@ -35,7 +35,8 @@ static acl_t smb_acl_to_posix(const struct smb_acl_t *acl); SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { struct smb_acl_t *result; acl_type_t acl_type; @@ -59,13 +60,13 @@ SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle, return NULL; } - result = smb_acl_to_internal(acl); + result = smb_acl_to_internal(acl, mem_ctx); acl_free(acl); return result; } SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, TALLOC_CTX *mem_ctx) { struct smb_acl_t *result; acl_t acl = acl_get_fd(fsp->fh->fd); @@ -74,7 +75,7 @@ SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle, return NULL; } - result = smb_acl_to_internal(acl); + result = smb_acl_to_internal(acl, mem_ctx); acl_free(acl); return result; } @@ -212,9 +213,9 @@ static bool smb_ace_to_internal(acl_entry_t posix_ace, return True; } -static struct smb_acl_t *smb_acl_to_internal(acl_t acl) +static struct smb_acl_t *smb_acl_to_internal(acl_t acl, TALLOC_CTX *mem_ctx) { - struct smb_acl_t *result = sys_acl_init(); + struct smb_acl_t *result = sys_acl_init(mem_ctx); int entry_id = ACL_FIRST_ENTRY; acl_entry_t e; if (result == NULL) { diff --git a/source3/modules/vfs_posixacl.h b/source3/modules/vfs_posixacl.h index 9ef3f86..b0fe841 100644 --- a/source3/modules/vfs_posixacl.h +++ b/source3/modules/vfs_posixacl.h @@ -23,10 +23,12 @@ SMB_ACL_T posixacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx); SMB_ACL_T posixacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp); + files_struct *fsp, + TALLOC_CTX *mem_ctx); int posixacl_sys_acl_set_file(vfs_handle_struct *handle, const char *name, diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c index 10b6f70..ad25e88 100644 --- a/source3/modules/vfs_solarisacl.c +++ b/source3/modules/vfs_solarisacl.c @@ -45,7 +45,7 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, SOLARIS_ACL_T *solariacl, int *count, SMB_ACL_TYPE_T type); static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solarisacl, int count, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx); static SOLARIS_ACL_TAG_T smb_tag_to_solaris_tag(SMB_ACL_TAG_T smb_tag); static SMB_ACL_TAG_T solaris_tag_to_smb_tag(SOLARIS_ACL_TAG_T solaris_tag); static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count, @@ -64,7 +64,7 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count); SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx) { SMB_ACL_T result = NULL; int count; @@ -85,7 +85,7 @@ SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, if (!solaris_acl_get_file(path_p, &solaris_acl, &count)) { goto done; } - result = solaris_acl_to_smb_acl(solaris_acl, count, type); + result = solaris_acl_to_smb_acl(solaris_acl, count, type, mem_ctx); if (result == NULL) { DEBUG(10, ("conversion solaris_acl -> smb_acl failed (%s).\n", strerror(errno))); @@ -103,7 +103,7 @@ SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, * get the access ACL of a file referred to by a fd */ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, TALLOC_CTX *mem_ctx) { SMB_ACL_T result = NULL; int count; @@ -424,12 +424,12 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, * soaris acl to the SMB_ACL format. */ static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx) { SMB_ACL_T result; int i; - if ((result = sys_acl_init()) == NULL) { + if ((result = sys_acl_init(mem_ctx)) == NULL) { DEBUG(10, ("error allocating memory for SMB_ACL\n")); goto fail; } diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index 7571b2f..b7d399b 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1772,14 +1772,15 @@ static int smb_time_audit_fchmod_acl(vfs_handle_struct *handle, static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type); + result = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type, mem_ctx); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; @@ -1791,14 +1792,15 @@ static SMB_ACL_T smb_time_audit_sys_acl_get_file(vfs_handle_struct *handle, } static SMB_ACL_T smb_time_audit_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result; struct timespec ts1,ts2; double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp); + result = SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; diff --git a/source3/modules/vfs_tru64acl.c b/source3/modules/vfs_tru64acl.c index 918f7c6..6eadee6 100644 --- a/source3/modules/vfs_tru64acl.c +++ b/source3/modules/vfs_tru64acl.c @@ -24,7 +24,8 @@ /* prototypes for private functions first - for clarity */ -static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl); +static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl, + TALLOC_CTX *mem_ctx); static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace, struct smb_acl_entry *smb_ace); static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl); @@ -38,7 +39,8 @@ static SMB_ACL_PERM_T tru64_permset_to_smb(const acl_perm_t tru64_permset); SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { struct smb_acl_t *result; acl_type_t the_acl_type; @@ -64,13 +66,14 @@ SMB_ACL_T tru64acl_sys_acl_get_file(vfs_handle_struct *handle, return NULL; } - result = tru64_acl_to_smb_acl(tru64_acl); + result = tru64_acl_to_smb_acl(tru64_acl, mem_ctx); acl_free(tru64_acl); return result; } SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, + TALLOC_CTX *mem_ctx) { struct smb_acl_t *result; acl_t tru64_acl = acl_get_fd(fsp->fh->fd, ACL_TYPE_ACCESS); @@ -79,7 +82,7 @@ SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle, return NULL; } - result = tru64_acl_to_smb_acl(tru64_acl); + result = tru64_acl_to_smb_acl(tru64_acl, mem_ctx); acl_free(tru64_acl); return result; } @@ -153,14 +156,15 @@ int tru64acl_sys_acl_delete_def_file(vfs_handle_struct *handle, /* private functions */ -static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl) +static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl, + TALLOC_CTX *mem_ctx) { struct smb_acl_t *result; acl_entry_t entry; DEBUG(10, ("Hi! This is tru64_acl_to_smb_acl.\n")); - if ((result = sys_acl_init()) == NULL) { + if ((result = sys_acl_init(mem_ctx)) == NULL) { DEBUG(0, ("sys_acl_init() failed in tru64_acl_to_smb_acl\n")); errno = ENOMEM; goto fail; diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index fe0f23a..96bd6ec 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -2934,7 +2934,7 @@ static bool set_canon_ace_list(files_struct *fsp, { connection_struct *conn = fsp->conn; bool ret = False; - SMB_ACL_T the_acl = sys_acl_init(); + SMB_ACL_T the_acl = sys_acl_init(talloc_tos()); canon_ace *p_ace; int i; SMB_ACL_ENTRY_T mask_entry; @@ -3694,7 +3694,7 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, } /* Get the ACL from the fd. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos()); pal = fload_inherited_info(fsp); @@ -3731,11 +3731,14 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, } /* Get the ACL from the path. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); + posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, + SMB_ACL_TYPE_ACCESS, talloc_tos()); /* If it's a directory get the default POSIX ACL. */ if(S_ISDIR(smb_fname.st.st_ex_mode)) { - def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); + def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, + SMB_ACL_TYPE_DEFAULT, + talloc_tos()); def_acl = free_empty_sys_acl(conn, def_acl); } @@ -4372,7 +4375,8 @@ int get_acl_group_bits( connection_struct *conn, const char *fname, mode_t *mode SMB_ACL_T posix_acl; int result = -1; - posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, SMB_ACL_TYPE_ACCESS); + posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, + SMB_ACL_TYPE_ACCESS, talloc_tos()); if (posix_acl == (SMB_ACL_T)NULL) return -1; @@ -4480,7 +4484,9 @@ static int copy_access_posix_acl(connection_struct *conn, const char *from, cons SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, SMB_ACL_TYPE_ACCESS)) == NULL) + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, from, + SMB_ACL_TYPE_ACCESS, + talloc_tos())) == NULL) return -1; if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) @@ -4511,7 +4517,9 @@ int chmod_acl(connection_struct *conn, const char *name, mode_t mode) 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); + SMB_ACL_T def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, + SMB_ACL_TYPE_DEFAULT, + talloc_tos()); bool has_acl = False; SMB_ACL_ENTRY_T entry; @@ -4550,7 +4558,7 @@ int fchmod_acl(files_struct *fsp, mode_t mode) SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp)) == NULL) + if ((posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos())) == NULL) return -1; if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) @@ -4632,10 +4640,13 @@ static bool unix_ex_wire_to_tagtype(unsigned char wire_tt, SMB_ACL_TAG_T *p_tt) FIXME ! How does the share mask/mode fit into this.... ? ****************************************************************************/ -static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, uint16 num_acls, const char *pdata) +static SMB_ACL_T create_posix_acl_from_wire(connection_struct *conn, + uint16 num_acls, + const char *pdata, + TALLOC_CTX *mem_ctx) { unsigned int i; - SMB_ACL_T the_acl = sys_acl_init(); + SMB_ACL_T the_acl = sys_acl_init(mem_ctx); if (the_acl == NULL) { return NULL; @@ -4748,7 +4759,9 @@ bool set_unix_posix_default_acl(connection_struct *conn, const char *fname, cons return True; } - if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, pdata)) == NULL) { + if ((def_acl = create_posix_acl_from_wire(conn, num_def_acls, + pdata, + talloc_tos())) == NULL) { return False; } @@ -4779,7 +4792,7 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c SMB_ACL_ENTRY_T entry; bool ret = False; /* Create a new ACL with only 3 entries, u/g/w. */ - SMB_ACL_T new_file_acl = sys_acl_init(); + SMB_ACL_T new_file_acl = sys_acl_init(talloc_tos()); SMB_ACL_ENTRY_T user_ent = NULL; SMB_ACL_ENTRY_T group_ent = NULL; SMB_ACL_ENTRY_T other_ent = NULL; @@ -4825,9 +4838,11 @@ static bool remove_posix_acl(connection_struct *conn, files_struct *fsp, const c /* Get the current file ACL. */ if (fsp && fsp->fh->fd != -1) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos()); } else { - file_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, SMB_ACL_TYPE_ACCESS); + file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, fname, + SMB_ACL_TYPE_ACCESS, + talloc_tos()); } if (file_acl == NULL) { @@ -4917,7 +4932,9 @@ bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * return remove_posix_acl(conn, fsp, fname); } - if ((file_acl = create_posix_acl_from_wire(conn, num_acls, pdata)) == NULL) { + if ((file_acl = create_posix_acl_from_wire(conn, num_acls, + pdata, + talloc_tos())) == NULL) { return False; } diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 9b9b358..32ddc2f 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -153,98 +153,99 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode) { + TALLOC_CTX *frame = talloc_stackframe(); + mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE; mode_t mode_user = (chmod_mode & 0700) >> 16; mode_t mode_group = (chmod_mode & 070) >> 8; mode_t mode_other = chmod_mode & 07; - SMB_ACL_ENTRY_T entry; - SMB_ACL_T acl = sys_acl_init(); + SMB_ACL_T acl = sys_acl_init(frame); if (!acl) { return NULL; } if (sys_acl_create_entry(&acl, &entry) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_tag_type(entry, SMB_ACL_USER_OBJ) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_permset(entry, &mode_user) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_create_entry(&acl, &entry) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP_OBJ) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_permset(entry, &mode_group) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_create_entry(&acl, &entry) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_tag_type(entry, SMB_ACL_OTHER) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_permset(entry, &mode_other) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (gid != -1) { if (sys_acl_create_entry(&acl, &entry) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_tag_type(entry, SMB_ACL_GROUP) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_qualifier(entry, &gid) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_permset(entry, &mode_group) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } } if (sys_acl_create_entry(&acl, &entry) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_tag_type(entry, SMB_ACL_MASK) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } if (sys_acl_set_permset(entry, &mode) != 0) { - TALLOC_FREE(acl); + TALLOC_FREE(frame); return NULL; } return acl; @@ -454,7 +455,7 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args) smbd_vfs_init(conn); - acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, acl_type); + acl = SMB_VFS_SYS_ACL_GET_FILE( conn, fname, acl_type, frame); if (!acl) { TALLOC_FREE(frame); status = map_nt_error_from_unix_common(errno); @@ -462,7 +463,6 @@ static PyObject *py_smbd_get_sys_acl(PyObject *self, PyObject *args) PyErr_NTSTATUS_IS_ERR_RAISE(status); } - talloc_steal(frame, acl); conn_free(conn); py_acl = py_return_ndr_struct("samba.dcerpc.smb_acl", "t", acl, acl); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 90d07d4..5d2cd15 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -4910,12 +4910,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, uint16 num_def_acls = 0; if (fsp && fsp->fh->fd != -1) { - file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp); + file_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, + talloc_tos()); } else { file_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, smb_fname->base_name, - SMB_ACL_TYPE_ACCESS); + SMB_ACL_TYPE_ACCESS, + talloc_tos()); } if (file_acl == NULL && no_acl_syscall_error(errno)) { @@ -4932,13 +4934,15 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn, SMB_VFS_SYS_ACL_GET_FILE( conn, fsp->fsp_name->base_name, - SMB_ACL_TYPE_DEFAULT); + SMB_ACL_TYPE_DEFAULT, + talloc_tos()); } else { def_acl = SMB_VFS_SYS_ACL_GET_FILE( conn, smb_fname->base_name, - SMB_ACL_TYPE_DEFAULT); + SMB_ACL_TYPE_DEFAULT, + talloc_tos()); } def_acl = free_empty_sys_acl(conn, def_acl); } diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index fe99ee2..182e334 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2221,17 +2221,19 @@ int smb_vfs_call_fchmod_acl(struct vfs_handle_struct *handle, SMB_ACL_T smb_vfs_call_sys_acl_get_file(struct vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { VFS_FIND(sys_acl_get_file); - return handle->fns->sys_acl_get_file_fn(handle, path_p, type); + return handle->fns->sys_acl_get_file_fn(handle, path_p, type, mem_ctx); } SMB_ACL_T smb_vfs_call_sys_acl_get_fd(struct vfs_handle_struct *handle, - struct files_struct *fsp) + struct files_struct *fsp, + TALLOC_CTX *mem_ctx) { VFS_FIND(sys_acl_get_fd); - return handle->fns->sys_acl_get_fd_fn(handle, fsp); + return handle->fns->sys_acl_get_fd_fn(handle, fsp, mem_ctx); } int smb_vfs_call_sys_acl_blob_get_file(struct vfs_handle_struct *handle, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 236b9c0..7755f8a 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1572,7 +1572,7 @@ static NTSTATUS cmd_sys_acl_get_fd(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - acl = SMB_VFS_SYS_ACL_GET_FD(vfs->files[fd]); + acl = SMB_VFS_SYS_ACL_GET_FD(vfs->files[fd], talloc_tos()); if (!acl) { printf("sys_acl_get_fd failed (%s)\n", strerror(errno)); return status; @@ -1597,7 +1597,7 @@ static NTSTATUS cmd_sys_acl_get_file(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, } type = atoi(argv[2]); - acl = SMB_VFS_SYS_ACL_GET_FILE(vfs->conn, argv[1], type); + acl = SMB_VFS_SYS_ACL_GET_FILE(vfs->conn, argv[1], type, talloc_tos()); if (!acl) { printf("sys_acl_get_file failed (%s)\n", strerror(errno)); return status; -- 1.7.11.7 From f8d5f5edb7752f5c6419fce5f8b71ab38f52f8ec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 10 Oct 2012 11:50:27 +1100 Subject: [PATCH 06/42] smbd: Add mem_ctx to {f,}get_nt_acl VFS call This makes it clear which context the returned SD is allocated on, as a number of callers do not want it on talloc_tos(). As the ACL transformation allocates and then no longer needs a great deal of memory, a talloc_stackframe() call is used to contain the memory that is not returned further up the stack. Andrew Bartlett --- examples/VFS/skel_opaque.c | 8 +++- examples/VFS/skel_transparent.c | 12 ++++-- source3/include/vfs.h | 4 ++ source3/include/vfs_macros.h | 18 ++++---- source3/modules/nfs4_acls.c | 18 +++++--- source3/modules/nfs4_acls.h | 2 + source3/modules/vfs_acl_common.c | 68 ++++++++++++++++++++----------- source3/modules/vfs_afsacl.c | 16 +++++--- source3/modules/vfs_aixacl2.c | 16 +++++--- source3/modules/vfs_catia.c | 3 +- source3/modules/vfs_default.c | 8 +++- source3/modules/vfs_full_audit.c | 12 ++++-- source3/modules/vfs_gpfs.c | 14 ++++--- source3/modules/vfs_media_harmony.c | 13 +++--- source3/modules/vfs_shadow_copy2.c | 11 +++-- source3/modules/vfs_time_audit.c | 8 +++- source3/modules/vfs_zfsacl.c | 18 ++++---- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 16 ++++---- source3/smbd/file_access.c | 4 +- source3/smbd/nttrans.c | 13 +++--- source3/smbd/open.c | 22 ++++++---- source3/smbd/posix_acls.c | 52 +++++++++++++++-------- source3/smbd/proto.h | 5 ++- source3/smbd/vfs.c | 6 ++- source3/torture/cmd_vfs.c | 8 +++- 25 files changed, 245 insertions(+), 130 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 3b91848..6dd83bb 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -545,13 +545,17 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle, } static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return NT_STATUS_NOT_IMPLEMENTED; } static NTSTATUS skel_get_nt_acl(vfs_handle_struct *handle, - const char *name, uint32 security_info, struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return NT_STATUS_NOT_IMPLEMENTED; } diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index a00b0e1..f8a743e 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -662,15 +662,19 @@ static NTSTATUS skel_fsctl(struct vfs_handle_struct *handle, } static NTSTATUS skel_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { - return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc); } static NTSTATUS skel_get_nt_acl(vfs_handle_struct *handle, - const char *name, uint32 security_info, struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { - return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, mem_ctx, ppdesc); } static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, diff --git a/source3/include/vfs.h b/source3/include/vfs.h index 4ba11be..2d18265 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -671,10 +671,12 @@ struct vfs_fn_pointers { NTSTATUS (*fget_nt_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS (*get_nt_acl_fn)(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS (*fset_nt_acl_fn)(struct vfs_handle_struct *handle, struct files_struct *fsp, @@ -1079,10 +1081,12 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle, NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h index f1bc8ff..a5ff90b 100644 --- a/source3/include/vfs_macros.h +++ b/source3/include/vfs_macros.h @@ -399,15 +399,15 @@ #define SMB_VFS_NEXT_FSCTL(handle, fsp, ctx, function, req_flags, in_data, in_len, out_data, max_out_len, out_len) \ smb_vfs_call_fsctl((handle)->next, (fsp), (ctx), (function), (req_flags), (in_data), (in_len), (out_data), (max_out_len), (out_len)) -#define SMB_VFS_FGET_NT_ACL(fsp, security_info, ppdesc) \ - smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (ppdesc)) -#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc) \ - smb_vfs_call_fget_nt_acl((handle)->next, (fsp), (security_info), (ppdesc)) - -#define SMB_VFS_GET_NT_ACL(conn, name, security_info, ppdesc) \ - smb_vfs_call_get_nt_acl((conn)->vfs_handles, (name), (security_info), (ppdesc)) -#define SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc) \ - smb_vfs_call_get_nt_acl((handle)->next, (name), (security_info), (ppdesc)) +#define SMB_VFS_FGET_NT_ACL(fsp, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_fget_nt_acl((fsp)->conn->vfs_handles, (fsp), (security_info), (mem_ctx), (ppdesc)) +#define SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_fget_nt_acl((handle)->next, (fsp), (security_info), (mem_ctx), (ppdesc)) + +#define SMB_VFS_GET_NT_ACL(conn, name, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_get_nt_acl((conn)->vfs_handles, (name), (security_info), (mem_ctx), (ppdesc)) +#define SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, mem_ctx, ppdesc) \ + smb_vfs_call_get_nt_acl((handle)->next, (name), (security_info), (mem_ctx), (ppdesc)) #define SMB_VFS_AUDIT_FILE(conn, name, sacl, access_requested, access_denied) \ smb_vfs_call_audit_file((conn)->vfs_handles, (name), (sacl), (access_requested), (access_denied)) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 05f90f7..48b045f 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -370,7 +370,7 @@ static bool smbacl4_nfs42win(TALLOC_CTX *mem_ctx, SMB4ACL_T *theacl, /* in */ } static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, - uint32 security_info, + uint32 security_info, TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { int good_aces = 0; @@ -378,7 +378,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, size_t sd_size = 0; struct security_ace *nt_ace_list = NULL; struct security_acl *psa = NULL; - TALLOC_CTX *mem_ctx = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (theacl==NULL || smb_get_naces(theacl)==0) return NT_STATUS_ACCESS_DENIED; /* special because we @@ -392,12 +392,14 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, S_ISDIR(sbuf->st_ex_mode), &nt_ace_list, &good_aces)==False) { DEBUG(8,("smbacl4_nfs42win failed\n")); + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } - psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, good_aces, nt_ace_list); + psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list); if (psa == NULL) { DEBUG(2,("make_sec_acl failed\n")); + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } @@ -409,6 +411,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, NULL, psa, &sd_size); if (*ppdesc==NULL) { DEBUG(2,("make_sec_desc failed\n")); + TALLOC_FREE(frame); return NT_STATUS_NO_MEMORY; } @@ -416,11 +419,13 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, "sd_size %d\n", (int)ndr_size_security_descriptor(*ppdesc, 0))); + TALLOC_FREE(frame); return NT_STATUS_OK; } NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { @@ -432,13 +437,15 @@ NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, + mem_ctx, ppdesc, theacl); } NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl) { @@ -450,7 +457,8 @@ NTSTATUS smb_get_nt_acl_nfs4(struct connection_struct *conn, return map_nt_error_from_unix(errno); } - return smb_get_nt_acl_nfs4_common(&sbuf, security_info, ppdesc, + return smb_get_nt_acl_nfs4_common(&sbuf, security_info, + mem_ctx, ppdesc, theacl); } diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h index fcab635..c461229 100644 --- a/source3/modules/nfs4_acls.h +++ b/source3/modules/nfs4_acls.h @@ -132,11 +132,13 @@ uint32 smb_get_naces(SMB4ACL_T *theacl); NTSTATUS smb_fget_nt_acl_nfs4(files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl); NTSTATUS smb_get_nt_acl_nfs4(connection_struct *conn, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, SMB4ACL_T *theacl); /* Callback function needed to set the native acl diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index c2ac875..ef2dda1 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -74,27 +74,29 @@ static NTSTATUS hash_sd_sha256(struct security_descriptor *psd, *******************************************************************/ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc, uint16_t *p_hash_type, uint8_t hash[XATTR_SD_HASH_SIZE]) { - TALLOC_CTX *ctx = talloc_tos(); struct xattr_NTACL xacl; enum ndr_err_code ndr_err; size_t sd_size; + TALLOC_CTX *frame = talloc_stackframe(); - ndr_err = ndr_pull_struct_blob(pblob, ctx, &xacl, + ndr_err = ndr_pull_struct_blob(pblob, frame, &xacl, (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n", ndr_errstr(ndr_err))); + TALLOC_FREE(frame); return ndr_map_error2ntstatus(ndr_err); } switch (xacl.version) { case 1: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd->owner_sid, xacl.info.sd->group_sid, @@ -106,7 +108,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memset(hash, '\0', XATTR_SD_HASH_SIZE); break; case 2: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd_hs2->sd->owner_sid, xacl.info.sd_hs2->sd->group_sid, @@ -118,7 +120,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memset(hash, '\0', XATTR_SD_HASH_SIZE); break; case 3: - *ppdesc = make_sec_desc(ctx, SD_REVISION, + *ppdesc = make_sec_desc(mem_ctx, SD_REVISION, xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE, xacl.info.sd_hs3->sd->owner_sid, xacl.info.sd_hs3->sd->group_sid, @@ -130,10 +132,11 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE); break; default: + TALLOC_FREE(frame); return NT_STATUS_REVISION_MISMATCH; } - TALLOC_FREE(xacl.info.sd); + TALLOC_FREE(frame); return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; } @@ -274,7 +277,8 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32_t security_info, - struct security_descriptor **ppdesc) + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { DATA_BLOB blob = data_blob_null; NTSTATUS status; @@ -298,14 +302,16 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, or to return as backup. */ if (fsp) { status = SMB_VFS_NEXT_FGET_NT_ACL(handle, - fsp, - HASH_SECURITY_INFO, - &pdesc_next); + fsp, + HASH_SECURITY_INFO, + mem_ctx, + &pdesc_next); } else { status = SMB_VFS_NEXT_GET_NT_ACL(handle, - name, - HASH_SECURITY_INFO, - &pdesc_next); + name, + HASH_SECURITY_INFO, + mem_ctx, + &pdesc_next); } if (!NT_STATUS_IS_OK(status)) { @@ -324,7 +330,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, goto out; } - status = parse_acl_blob(&blob, &psd, + status = parse_acl_blob(&blob, mem_ctx, &psd, &hash_type, &hash[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", @@ -417,7 +423,7 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, if (ignore_file_system_acl) { TALLOC_FREE(pdesc_next); - status = make_default_filesystem_acl(talloc_tos(), + status = make_default_filesystem_acl(mem_ctx, name, psbuf, &psd); @@ -476,11 +482,14 @@ static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle, Fetch a security descriptor given an fsp. *********************************************************************/ -static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, - uint32_t security_info, struct security_descriptor **ppdesc) +static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, + files_struct *fsp, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return get_nt_acl_internal(handle, fsp, - NULL, security_info, ppdesc); + NULL, security_info, mem_ctx, ppdesc); } /********************************************************************* @@ -488,10 +497,13 @@ static NTSTATUS fget_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, *********************************************************************/ static NTSTATUS get_nt_acl_common(vfs_handle_struct *handle, - const char *name, uint32_t security_info, struct security_descriptor **ppdesc) + const char *name, + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { return get_nt_acl_internal(handle, NULL, - name, security_info, ppdesc); + name, security_info, mem_ctx, ppdesc); } /********************************************************************* @@ -507,6 +519,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, struct security_descriptor *psd = NULL; uint8_t hash[XATTR_SD_HASH_SIZE]; bool chown_needed = false; + TALLOC_CTX *frame = talloc_stackframe(); if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -518,9 +531,11 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = get_nt_acl_internal(handle, fsp, NULL, SECINFO_OWNER|SECINFO_GROUP|SECINFO_DACL|SECINFO_SACL, + frame, &psd); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -554,6 +569,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + TALLOC_FREE(frame); return status; } /* We got access denied here. If we're already root, @@ -578,22 +594,26 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, security_info_sent, psd); unbecome_root(); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } } /* Get the full underlying sd, then hash. */ status = SMB_VFS_NEXT_FGET_NT_ACL(handle, - fsp, - HASH_SECURITY_INFO, - &pdesc_next); + fsp, + HASH_SECURITY_INFO, + frame, + &pdesc_next); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } status = hash_sd_sha256(pdesc_next, hash); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -610,11 +630,13 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = create_acl_blob(psd, &blob, XATTR_SD_HASH_TYPE_SHA256, hash); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("fset_nt_acl_xattr: create_acl_blob failed\n")); + TALLOC_FREE(frame); return status; } status = store_acl_blob_fsp(handle, fsp, &blob); + TALLOC_FREE(frame); return status; } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 770f6a3..96521bc 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -594,6 +594,7 @@ static uint32 nt_to_afs_file_rights(const char *filename, const struct security_ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, SMB_STRUCT_STAT *psbuf, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct security_ace *nt_ace_list; @@ -601,7 +602,6 @@ static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl, struct security_acl *psa = NULL; int good_aces; size_t sd_size; - TALLOC_CTX *mem_ctx = talloc_tos(); struct afs_ace *afs_ace; @@ -663,6 +663,7 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, struct connection_struct *conn, struct smb_filename *smb_fname, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { int ret; @@ -678,12 +679,13 @@ static size_t afs_to_nt_acl(struct afs_acl *afs_acl, } return afs_to_nt_acl_common(afs_acl, &smb_fname->st, security_info, - ppdesc); + mem_ctx, ppdesc); } static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB_STRUCT_STAT sbuf; @@ -691,7 +693,7 @@ static size_t afs_fto_nt_acl(struct afs_acl *afs_acl, if (fsp->fh->fd == -1) { /* Get the stat struct for the owner info. */ return afs_to_nt_acl(afs_acl, fsp->conn, fsp->fsp_name, - security_info, ppdesc); + security_info, mem_ctx, ppdesc); } if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) { @@ -1008,6 +1010,7 @@ static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct afs_acl acl; @@ -1021,7 +1024,7 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, return NT_STATUS_ACCESS_DENIED; } - sd_size = afs_fto_nt_acl(&acl, fsp, security_info, ppdesc); + sd_size = afs_fto_nt_acl(&acl, fsp, security_info, mem_ctx, ppdesc); free_afs_acl(&acl); @@ -1029,7 +1032,8 @@ static NTSTATUS afsacl_fget_nt_acl(struct vfs_handle_struct *handle, } static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, - const char *name, uint32 security_info, + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct afs_acl acl; @@ -1053,7 +1057,7 @@ static NTSTATUS afsacl_get_nt_acl(struct vfs_handle_struct *handle, } sd_size = afs_to_nt_acl(&acl, handle->conn, smb_fname, security_info, - ppdesc); + mem_ctx, ppdesc); TALLOC_FREE(smb_fname); free_afs_acl(&acl); diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index 0d754d7..0f89eb6 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -157,6 +157,7 @@ static bool aixjfs2_get_nfs4_acl(const char *name, static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; @@ -169,17 +170,21 @@ static NTSTATUS aixjfs2_fget_nt_acl(vfs_handle_struct *handle, if (retryPosix) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_fget_nt_acl(fsp, security_info, ppdesc); + return posix_fget_nt_acl(fsp, security_info, + mem_ctx, ppdesc); } if (result==False) return NT_STATUS_ACCESS_DENIED; - return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, + mem_ctx, pacl); } static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle, const char *name, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; bool result; @@ -191,12 +196,13 @@ static NTSTATUS aixjfs2_get_nt_acl(vfs_handle_struct *handle, { DEBUG(10, ("retrying with posix acl...\n")); return posix_get_nt_acl(handle->conn, name, security_info, - ppdesc); + mem_ctx, ppdesc); } if (result==False) return NT_STATUS_ACCESS_DENIED; - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); } diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index a2bef44..b9f241e 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -703,6 +703,7 @@ static NTSTATUS catia_get_nt_acl(struct vfs_handle_struct *handle, const char *path, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { char *mapped_name = NULL; @@ -715,7 +716,7 @@ catia_get_nt_acl(struct vfs_handle_struct *handle, return status; } status = SMB_VFS_NEXT_GET_NT_ACL(handle, mapped_name, - security_info, ppdesc); + security_info, mem_ctx, ppdesc); TALLOC_FREE(mapped_name); return status; diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index a03a4f8..84d12e3 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -2056,12 +2056,14 @@ static void vfswrap_strict_unlock(struct vfs_handle_struct *handle, static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; START_PROFILE(fget_nt_acl); - result = posix_fget_nt_acl(fsp, security_info, ppdesc); + result = posix_fget_nt_acl(fsp, security_info, + mem_ctx, ppdesc); END_PROFILE(fget_nt_acl); return result; } @@ -2069,12 +2071,14 @@ static NTSTATUS vfswrap_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS vfswrap_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; START_PROFILE(get_nt_acl); - result = posix_get_nt_acl(handle->conn, name, security_info, ppdesc); + result = posix_get_nt_acl(handle->conn, name, security_info, + mem_ctx, ppdesc); END_PROFILE(get_nt_acl); return result; } diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index e56c4a8..be8989c 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -1733,12 +1733,14 @@ static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle, } static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, - struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { NTSTATUS result; - result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); do_log(SMB_VFS_OP_FGET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp_str_do_log(fsp)); @@ -1749,11 +1751,13 @@ static NTSTATUS smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_stru static NTSTATUS smb_full_audit_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; - result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, + mem_ctx, ppdesc); do_log(SMB_VFS_OP_GET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", name); diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 412c48c..5ab5d4a 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -348,6 +348,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; @@ -367,11 +368,11 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl); if (result == 0) - return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + return smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl); if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_fget_nt_acl(fsp, security_info, ppdesc); + return posix_fget_nt_acl(fsp, security_info, mem_ctx, ppdesc); } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ @@ -380,7 +381,8 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, const char *name, - uint32 security_info, struct security_descriptor **ppdesc) + uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB4ACL_T *pacl = NULL; int result; @@ -399,11 +401,13 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, result = gpfs_get_nfs4_acl(name, &pacl); if (result == 0) - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl); + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); - return posix_get_nt_acl(handle->conn, name, security_info, ppdesc); + return posix_get_nt_acl(handle->conn, name, security_info, + mem_ctx, ppdesc); } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ diff --git a/source3/modules/vfs_media_harmony.c b/source3/modules/vfs_media_harmony.c index a10eb5e..360fca6 100644 --- a/source3/modules/vfs_media_harmony.c +++ b/source3/modules/vfs_media_harmony.c @@ -2009,9 +2009,10 @@ out: * In this case, "name" is a path. */ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, - const char *name, - uint32 security_info, - struct security_descriptor **ppdesc) + const char *name, + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { NTSTATUS status; char *clientPath; @@ -2021,7 +2022,8 @@ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, if (!is_in_media_files(name)) { status = SMB_VFS_NEXT_GET_NT_ACL(handle, name, - security_info, ppdesc); + security_info, + mem_ctx, ppdesc); goto out; } @@ -2037,7 +2039,8 @@ static NTSTATUS mh_get_nt_acl(vfs_handle_struct *handle, } status = SMB_VFS_NEXT_GET_NT_ACL(handle, clientPath, - security_info, ppdesc); + security_info, + mem_ctx, ppdesc); err: TALLOC_FREE(clientPath); out: diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c index 7c42052..1cf8e37 100644 --- a/source3/modules/vfs_shadow_copy2.c +++ b/source3/modules/vfs_shadow_copy2.c @@ -1188,6 +1188,7 @@ static int shadow_copy2_get_shadow_copy_data( static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { time_t timestamp; @@ -1202,6 +1203,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, } if (timestamp == 0) { return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); } conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); @@ -1209,7 +1211,8 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, if (conv == NULL) { return map_nt_error_from_unix(errno); } - status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc); + status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, + mem_ctx, ppdesc); TALLOC_FREE(conv); return status; } @@ -1217,6 +1220,7 @@ static NTSTATUS shadow_copy2_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, const char *fname, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { time_t timestamp; @@ -1230,14 +1234,15 @@ static NTSTATUS shadow_copy2_get_nt_acl(vfs_handle_struct *handle, } if (timestamp == 0) { return SMB_VFS_NEXT_GET_NT_ACL(handle, fname, security_info, - ppdesc); + mem_ctx, ppdesc); } conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); TALLOC_FREE(stripped); if (conv == NULL) { return map_nt_error_from_unix(errno); } - status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, ppdesc); + status = SMB_VFS_NEXT_GET_NT_ACL(handle, conv, security_info, + mem_ctx, ppdesc); TALLOC_FREE(conv); return status; } diff --git a/source3/modules/vfs_time_audit.c b/source3/modules/vfs_time_audit.c index b7d399b..6ff1a55 100644 --- a/source3/modules/vfs_time_audit.c +++ b/source3/modules/vfs_time_audit.c @@ -1671,6 +1671,7 @@ static NTSTATUS smb_time_audit_translate_name(struct vfs_handle_struct *handle, static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; @@ -1678,7 +1679,8 @@ static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); + result = SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, + mem_ctx, ppdesc); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; @@ -1692,6 +1694,7 @@ static NTSTATUS smb_time_audit_fget_nt_acl(vfs_handle_struct *handle, static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { NTSTATUS result; @@ -1699,7 +1702,8 @@ static NTSTATUS smb_time_audit_get_nt_acl(vfs_handle_struct *handle, double timediff; clock_gettime_mono(&ts1); - result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); + result = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, + mem_ctx, ppdesc); clock_gettime_mono(&ts2); timediff = nsec_time_diff(&ts2,&ts1)*1.0e-9; diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index 7858a6a..bf06881 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -192,14 +192,16 @@ static NTSTATUS zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, } static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, - struct files_struct *fsp, - uint32 security_info, - struct security_descriptor **ppdesc) + struct files_struct *fsp, + uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl; NTSTATUS status; - status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, security_info, + status = zfs_get_nt_acl_common(fsp->fsp_name->base_name, + mem_ctx, security_info, &pacl); if (!NT_STATUS_IS_OK(status)) { return status; @@ -209,8 +211,9 @@ static NTSTATUS zfsacl_fget_nt_acl(struct vfs_handle_struct *handle, } static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle, - const char *name, uint32 security_info, - struct security_descriptor **ppdesc) + const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB4ACL_T *pacl; NTSTATUS status; @@ -220,7 +223,8 @@ static NTSTATUS zfsacl_get_nt_acl(struct vfs_handle_struct *handle, return status; } - return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, + mem_ctx, ppdesc, pacl); } diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index 696c7bf..fb2a69e 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2088,15 +2088,22 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } + sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf); + if (!sd_buf) { + werr = WERR_NOMEM; + goto error_exit; + } + nt_status = SMB_VFS_FGET_NT_ACL(fsp, (SECINFO_OWNER |SECINFO_GROUP - |SECINFO_DACL), &psd); + |SECINFO_DACL), sd_buf, &sd_buf->sd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srvsvc_NetGetFileSecurity: Unable to get NT ACL " "for file %s\n", smb_fname_str_dbg(smb_fname))); werr = ntstatus_to_werror(nt_status); + TALLOC_FREE(sd_buf); goto error_exit; } @@ -2106,14 +2113,7 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, sd_size = ndr_size_security_descriptor(psd, 0); - sd_buf = talloc_zero(p->mem_ctx, struct sec_desc_buf); - if (!sd_buf) { - werr = WERR_NOMEM; - goto error_exit; - } - sd_buf->sd_size = sd_size; - sd_buf->sd = talloc_move(p->mem_ctx, &psd); *r->out.sd_buf = sd_buf; diff --git a/source3/smbd/file_access.c b/source3/smbd/file_access.c index 6ced6a6..96a89e7 100644 --- a/source3/smbd/file_access.c +++ b/source3/smbd/file_access.c @@ -149,11 +149,11 @@ bool can_write_to_file(connection_struct *conn, bool directory_has_default_acl(connection_struct *conn, const char *fname) { - /* returns talloced off tos. */ struct security_descriptor *secdesc = NULL; unsigned int i; NTSTATUS status = SMB_VFS_GET_NT_ACL(conn, fname, - SECINFO_DACL, &secdesc); + SECINFO_DACL, talloc_tos(), + &secdesc); if (!NT_STATUS_IS_OK(status) || secdesc == NULL || diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 997f721..1a82a02 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1905,6 +1905,7 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, { NTSTATUS status; struct security_descriptor *psd = NULL; + TALLOC_CTX *frame = talloc_stackframe(); /* * Get the permissions to return. @@ -1930,13 +1931,13 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, } if (!lp_nt_acl_support(SNUM(conn))) { - status = get_null_nt_acl(mem_ctx, &psd); + status = get_null_nt_acl(frame, &psd); } else if (security_info_wanted & SECINFO_LABEL) { /* Like W2K3 return a null object. */ - status = get_null_nt_acl(mem_ctx, &psd); + status = get_null_nt_acl(frame, &psd); } else { status = SMB_VFS_FGET_NT_ACL( - fsp, security_info_wanted, &psd); + fsp, security_info_wanted, frame, &psd); } if (!NT_STATUS_IS_OK(status)) { return status; @@ -1987,7 +1988,7 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, } if (max_data_count < *psd_size) { - TALLOC_FREE(psd); + TALLOC_FREE(frame); return NT_STATUS_BUFFER_TOO_SMALL; } @@ -1995,11 +1996,11 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, ppmarshalled_sd, psd_size); if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(psd); + TALLOC_FREE(frame); return status; } - TALLOC_FREE(psd); + TALLOC_FREE(frame); return NT_STATUS_OK; } diff --git a/source3/smbd/open.c b/source3/smbd/open.c index a9a9198..d239f98 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -114,7 +114,7 @@ NTSTATUS smbd_check_access_rights(struct connection_struct *conn, status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | - SECINFO_DACL),&sd); + SECINFO_DACL), talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("smbd_check_access_rights: Could not get acl " @@ -236,6 +236,7 @@ static NTSTATUS check_parent_access(struct connection_struct *conn, status = SMB_VFS_GET_NT_ACL(conn, parent_dir, SECINFO_DACL, + talloc_tos(), &parent_sd); if (!NT_STATUS_IS_OK(status)) { @@ -1675,7 +1676,8 @@ static NTSTATUS smbd_calculate_maximum_allowed_access( status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name, (SECINFO_OWNER | SECINFO_GROUP | - SECINFO_DACL),&sd); + SECINFO_DACL), + talloc_tos(), &sd); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* @@ -3407,7 +3409,7 @@ NTSTATUS open_streams_for_delete(connection_struct *conn, static NTSTATUS inherit_new_acl(files_struct *fsp) { - TALLOC_CTX *ctx = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); char *parent_name = NULL; struct security_descriptor *parent_desc = NULL; NTSTATUS status = NT_STATUS_OK; @@ -3419,14 +3421,15 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) bool inheritable_components = false; size_t size = 0; - if (!parent_dirname(ctx, fsp->fsp_name->base_name, &parent_name, NULL)) { + if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) { return NT_STATUS_NO_MEMORY; } status = SMB_VFS_GET_NT_ACL(fsp->conn, - parent_name, - (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL), - &parent_desc); + parent_name, + (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL), + frame, + &parent_desc); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -3435,6 +3438,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) fsp->is_directory); if (!inheritable_components && !inherit_owner) { + TALLOC_FREE(frame); /* Nothing to inherit and not setting owner. */ return NT_STATUS_OK; } @@ -3460,7 +3464,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) group_sid = &fsp->conn->session_info->security_token->sids[PRIMARY_GROUP_SID_INDEX]; } - status = se_create_child_secdesc(ctx, + status = se_create_child_secdesc(frame, &psd, &size, parent_desc, @@ -3468,6 +3472,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) group_sid, fsp->is_directory); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } @@ -3498,6 +3503,7 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) if (inherit_owner) { unbecome_root(); } + TALLOC_FREE(frame); return status; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 96bd6ec..7f12f4b 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3408,6 +3408,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, SMB_ACL_T posix_acl, SMB_ACL_T def_acl, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { struct dom_sid owner_sid; @@ -3620,7 +3621,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, } } /* security_info & SECINFO_DACL */ - psd = make_standard_sec_desc( talloc_tos(), + psd = make_standard_sec_desc(mem_ctx, (security_info & SECINFO_OWNER) ? &owner_sid : NULL, (security_info & SECINFO_GROUP) ? &group_sid : NULL, psa, @@ -3671,11 +3672,14 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, } NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { SMB_STRUCT_STAT sbuf; SMB_ACL_T posix_acl = NULL; struct pai_val *pal; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; *ppdesc = NULL; @@ -3684,33 +3688,42 @@ NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, /* can it happen that fsp_name == NULL ? */ if (fsp->is_directory || fsp->fh->fd == -1) { - return posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, - security_info, ppdesc); + status = posix_get_nt_acl(fsp->conn, fsp->fsp_name->base_name, + security_info, mem_ctx, ppdesc); + TALLOC_FREE(frame); + return status; } /* Get the stat struct for the owner info. */ if(SMB_VFS_FSTAT(fsp, &sbuf) != 0) { + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } /* Get the ACL from the fd. */ - posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, talloc_tos()); + posix_acl = SMB_VFS_SYS_ACL_GET_FD(fsp, frame); pal = fload_inherited_info(fsp); - return posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, - &sbuf, pal, posix_acl, NULL, - security_info, ppdesc); + status = posix_get_nt_acl_common(fsp->conn, fsp->fsp_name->base_name, + &sbuf, pal, posix_acl, NULL, + security_info, mem_ctx, ppdesc); + TALLOC_FREE(frame); + return status; } NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, - uint32_t security_info, struct security_descriptor **ppdesc) + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) { SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; struct smb_filename smb_fname; int ret; + TALLOC_CTX *frame = talloc_stackframe(); + NTSTATUS status; *ppdesc = NULL; @@ -3727,26 +3740,29 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, } if (ret == -1) { + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } /* Get the ACL from the path. */ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, - SMB_ACL_TYPE_ACCESS, talloc_tos()); + SMB_ACL_TYPE_ACCESS, frame); /* If it's a directory get the default POSIX ACL. */ if(S_ISDIR(smb_fname.st.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, - SMB_ACL_TYPE_DEFAULT, - talloc_tos()); + SMB_ACL_TYPE_DEFAULT, frame); def_acl = free_empty_sys_acl(conn, def_acl); } pal = load_inherited_info(conn, name); - return posix_get_nt_acl_common(conn, name, &smb_fname.st, pal, - posix_acl, def_acl, security_info, - ppdesc); + status = posix_get_nt_acl_common(conn, name, &smb_fname.st, pal, + posix_acl, def_acl, security_info, + mem_ctx, + ppdesc); + TALLOC_FREE(frame); + return status; } /**************************************************************************** @@ -4972,7 +4988,7 @@ bool set_unix_posix_acl(connection_struct *conn, files_struct *fsp, const char * struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname, uint32 security_info_wanted) { - struct security_descriptor *psd, *ret_sd; + struct security_descriptor *ret_sd; connection_struct *conn; files_struct finfo; struct fd_handle fh; @@ -5018,7 +5034,9 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna return NULL; } - if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, security_info_wanted, &psd))) { + if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, + security_info_wanted, + ctx, &ret_sd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); TALLOC_FREE(finfo.fsp_name); conn_free(conn); @@ -5026,8 +5044,6 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna return NULL; } - ret_sd = dup_sec_desc( ctx, psd ); - TALLOC_FREE(finfo.fsp_name); conn_free(conn); TALLOC_FREE(frame); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index a4b2fab..2e53a87 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -711,9 +711,12 @@ NTSTATUS unpack_nt_owners(connection_struct *conn, uid_t *puser, gid_t *pgrp, ui bool current_user_in_group(connection_struct *conn, gid_t gid); SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl); NTSTATUS posix_fget_nt_acl(struct files_struct *fsp, uint32_t security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc); NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, - uint32_t security_info, struct security_descriptor **ppdesc); + uint32_t security_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc); NTSTATUS try_chown(files_struct *fsp, uid_t uid, gid_t gid); NTSTATUS append_parent_acl(files_struct *fsp, const struct security_descriptor *pcsd, diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 182e334..3a95c58 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -2165,20 +2165,22 @@ NTSTATUS smb_vfs_call_fsctl(struct vfs_handle_struct *handle, NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle, struct files_struct *fsp, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { VFS_FIND(fget_nt_acl); return handle->fns->fget_nt_acl_fn(handle, fsp, security_info, - ppdesc); + mem_ctx, ppdesc); } NTSTATUS smb_vfs_call_get_nt_acl(struct vfs_handle_struct *handle, const char *name, uint32 security_info, + TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc) { VFS_FIND(get_nt_acl); - return handle->fns->get_nt_acl_fn(handle, name, security_info, ppdesc); + return handle->fns->get_nt_acl_fn(handle, name, security_info, mem_ctx, ppdesc); } NTSTATUS smb_vfs_call_fset_nt_acl(struct vfs_handle_struct *handle, diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index 7755f8a..a37c9fc 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1374,7 +1374,9 @@ static NTSTATUS cmd_fget_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - status = SMB_VFS_FGET_NT_ACL(vfs->files[fd], SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, &sd); + status = SMB_VFS_FGET_NT_ACL(vfs->files[fd], + SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, + talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { printf("fget_nt_acl returned (%s)\n", nt_errstr(status)); return status; @@ -1395,7 +1397,9 @@ static NTSTATUS cmd_get_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - status = SMB_VFS_GET_NT_ACL(vfs->conn, argv[1], SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, &sd); + status = SMB_VFS_GET_NT_ACL(vfs->conn, argv[1], + SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL, + talloc_tos(), &sd); if (!NT_STATUS_IS_OK(status)) { printf("get_nt_acl returned (%s)\n", nt_errstr(status)); return status; -- 1.7.11.7 From 2babb9d9c91fab7bde75f2d6798a426330e4cf04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Oct 2012 15:08:25 +1100 Subject: [PATCH 07/42] rpc_server:srvsvc Remove psd variable that was no longer set by SMB_VFS_FGET_NT_ACL This fixes up an error introduced by c8ade07760ae0ccfdf2d875c9f3027926e62321b. Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Oct 11 07:53:36 CEST 2012 on sn-devel-104 --- source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c index fb2a69e..a6472a6 100644 --- a/source3/rpc_server/srvsvc/srv_srvsvc_nt.c +++ b/source3/rpc_server/srvsvc/srv_srvsvc_nt.c @@ -2009,7 +2009,6 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, struct srvsvc_NetGetFileSecurity *r) { struct smb_filename *smb_fname = NULL; - struct security_descriptor *psd = NULL; size_t sd_size; char *servicename = NULL; SMB_STRUCT_STAT st; @@ -2107,11 +2106,11 @@ WERROR _srvsvc_NetGetFileSecurity(struct pipes_struct *p, goto error_exit; } - if (psd && psd->dacl) { - psd->dacl->revision = NT4_ACL_REVISION; + if (sd_buf->sd->dacl) { + sd_buf->sd->dacl->revision = NT4_ACL_REVISION; } - sd_size = ndr_size_security_descriptor(psd, 0); + sd_size = ndr_size_security_descriptor(sd_buf->sd, 0); sd_buf->sd_size = sd_size; @@ -2141,7 +2140,6 @@ error_exit: done: - TALLOC_FREE(psd); TALLOC_FREE(smb_fname); return werr; -- 1.7.11.7 From 36dcaa30702df38b267e89925c32d550a5f5defb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 11 Oct 2012 22:29:43 +1100 Subject: [PATCH 08/42] smbd: Always free the talloc_stackframe() before leaving smbd_do_query_security_desc Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Oct 11 15:20:54 CEST 2012 on sn-devel-104 --- source3/smbd/nttrans.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 1a82a02..54e475d 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1914,12 +1914,14 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, if ((security_info_wanted & SECINFO_SACL) && !(fsp->access_mask & SEC_FLAG_SYSTEM_SECURITY)) { DEBUG(10, ("Access to SACL denied.\n")); + TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; } if ((security_info_wanted & (SECINFO_DACL|SECINFO_OWNER|SECINFO_GROUP)) && !(fsp->access_mask & SEC_STD_READ_CONTROL)) { DEBUG(10, ("Access to DACL, OWNER, or GROUP denied.\n")); + TALLOC_FREE(frame); return NT_STATUS_ACCESS_DENIED; } @@ -1940,6 +1942,7 @@ NTSTATUS smbd_do_query_security_desc(connection_struct *conn, fsp, security_info_wanted, frame, &psd); } if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return status; } -- 1.7.11.7 From 3660bca69619c6c1b38f93380c0c1ba1af55c5cf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 23 Oct 2012 16:13:28 +1100 Subject: [PATCH 09/42] vfs: Fix compilation of ACL support on solaris --- source3/modules/vfs_solarisacl.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source3/modules/vfs_solarisacl.h b/source3/modules/vfs_solarisacl.h index 84c2cb7..20f1051 100644 --- a/source3/modules/vfs_solarisacl.h +++ b/source3/modules/vfs_solarisacl.h @@ -22,10 +22,12 @@ SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, const char *path_p, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx); SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp); + files_struct *fsp, + TALLOC_CTX *mem_ctx); int solarisacl_sys_acl_set_file(vfs_handle_struct *handle, const char *name, -- 1.7.11.7 From c991387c3dff728a0a00170540f953e05e8af1d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Oct 2012 16:25:22 +1100 Subject: [PATCH 10/42] pysmbd: Fix pysmbd octal mode handling It is clearly too long since Computer Science 101... ;-) Andrew Bartlett --- source3/smbd/pysmbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 32ddc2f..5035bda 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -157,8 +157,8 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode) mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE; - mode_t mode_user = (chmod_mode & 0700) >> 16; - mode_t mode_group = (chmod_mode & 070) >> 8; + mode_t mode_user = (chmod_mode & 0700) >> 6; + mode_t mode_group = (chmod_mode & 070) >> 3; mode_t mode_other = chmod_mode & 07; SMB_ACL_ENTRY_T entry; SMB_ACL_T acl = sys_acl_init(frame); -- 1.7.11.7 From d6d5b0b5bf8c2f63a87ae4cff69948b9d2c23c14 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Oct 2012 16:27:19 +1100 Subject: [PATCH 11/42] selftest: Add many more tests for our posix ACL handling This tests the mapping of posix ACLs to NT ACLs, the invalidation of NT ACLs stored as an xattr and ensures this security-critical code continues to work in the long term. Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Oct 25 10:05:16 CEST 2012 on sn-devel-104 --- source4/scripting/python/samba/tests/posixacl.py | 237 ++++++++++++++++++++++- 1 file changed, 236 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 78a07f7..449a87c 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -18,7 +18,7 @@ """Tests for the Samba3 NT -> posix ACL layer""" -from samba.ntacls import setntacl, getntacl +from samba.ntacls import setntacl, getntacl, checkset_backend from samba.dcerpc import xattr, security, smb_acl, idmap from samba.param import LoadParm from samba.tests import TestCase @@ -61,6 +61,70 @@ class PosixAclMappingTests(TestCase): self.assertEquals(facl.as_sddl(anysid),acl) os.unlink(tempf) + def test_setntacl_smbd_setposixacl_getntacl(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + + # This will invalidate the ACL, as we have a hook! + smbd.set_simple_acl(tempf, 0640) + + # However, this only asks the xattr + try: + facl = getntacl(lp,tempf, direct_db_access=True) + self.assertTrue(False) + except TypeError: + pass + os.unlink(tempf) + + def test_setntacl_smbd_chmod_getntacl(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + + # This should invalidate the ACL, as we include the posix ACL in the hash + (backend_obj, dbname) = checkset_backend(lp, None, None) + backend_obj.wrap_setxattr(dbname, + tempf, "system.fake_access_acl", "") + + #however, as this is direct DB access, we do not notice it + facl = getntacl(lp,tempf, direct_db_access=True) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(acl, facl.as_sddl(anysid)) + os.unlink(tempf) + + def test_setntacl_smbd_chmod_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + + # This should invalidate the ACL, as we include the posix ACL in the hash + (backend_obj, dbname) = checkset_backend(lp, None, None) + backend_obj.wrap_setxattr(dbname, + tempf, "system.fake_access_acl", "") + + #the hash breaks, and we return an ACL based only on the mode + facl = getntacl(lp,tempf) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) + os.unlink(tempf) + def test_setntacl_getntacl_smbd(self): random.seed() lp = LoadParm() @@ -89,6 +153,46 @@ class PosixAclMappingTests(TestCase): self.assertEquals(facl.as_sddl(anysid),acl) os.unlink(tempf) + def test_setntacl_smbd_setposixacl_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + # This invalidates the hash of the NT acl just set + smbd.set_simple_acl(tempf, 0640) + facl = getntacl(lp,tempf, direct_db_access=False) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) + os.unlink(tempf) + + def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;BA)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + # This invalidates the hash of the NT acl just set + s3conf = s3param.get_context() + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) + smbd.set_simple_acl(tempf, 0640, BA_gid) + + # This should re-calculate an ACL based on the posix details + facl = getntacl(lp,tempf, direct_db_access=False) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) + os.unlink(tempf) + def test_setntacl_smbd_getntacl_smbd_gpo(self): random.seed() lp = LoadParm() @@ -118,6 +222,137 @@ class PosixAclMappingTests(TestCase): posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) os.unlink(tempf) + def test_setposixacl_getposixacl(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + smbd.set_simple_acl(tempf, 0640) + posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + self.assertEquals(posix_acl.count, 4) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[0].a_perm, 6) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[1].a_perm, 4) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[3].a_perm, 6) + os.unlink(tempf) + + def test_setposixacl_getntacl(self): + random.seed() + lp = LoadParm() + acl = "" + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + smbd.set_simple_acl(tempf, 0750) + try: + facl = getntacl(lp,tempf) + except TypeError: + # We don't expect the xattr to be filled in in this case + pass + + def test_setposixacl_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + s3conf = s3param.get_context() + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + group_SID = s4_passdb.gid_to_sid(os.stat(tempf).st_gid) + user_SID = s4_passdb.uid_to_sid(os.stat(tempf).st_uid) + smbd.set_simple_acl(tempf, 0640) + facl = getntacl(lp, tempf, direct_db_access=False) + domsid = passdb.get_global_sam_sid() + acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(acl, facl.as_sddl(anysid)) + + def test_setposixacl_group_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + s3conf = s3param.get_context() + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) + group_SID = s4_passdb.gid_to_sid(os.stat(tempf).st_gid) + user_SID = s4_passdb.uid_to_sid(os.stat(tempf).st_uid) + self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) + smbd.set_simple_acl(tempf, 0640, BA_gid) + facl = getntacl(lp, tempf, direct_db_access=False) + domsid = passdb.get_global_sam_sid() + acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(acl, facl.as_sddl(anysid)) + + def test_setposixacl_getposixacl(self): + random.seed() + lp = LoadParm() + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + smbd.set_simple_acl(tempf, 0640) + posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + self.assertEquals(posix_acl.count, 4) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[0].a_perm, 6) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[1].a_perm, 4) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[3].a_perm, 6) + os.unlink(tempf) + + def test_setposixacl_group_getposixacl(self): + random.seed() + lp = LoadParm() + path = os.environ['SELFTEST_PREFIX'] + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + s3conf = s3param.get_context() + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) + self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) + smbd.set_simple_acl(tempf, 0670, BA_gid) + posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + + self.assertEquals(posix_acl.count, 5) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[0].a_perm, 6) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[1].a_perm, 7) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[3].a_perm, 7) + self.assertEquals(posix_acl.acl[3].info.gid, BA_gid) + + self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[4].a_perm, 6) + os.unlink(tempf) + def test_setntacl_sysvol_check_getposixacl(self): random.seed() lp = LoadParm() -- 1.7.11.7 From a0fb8f3abeb51677a1e004aa9d26966a1604d72e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Oct 2012 19:58:15 +1100 Subject: [PATCH 12/42] selftest: Cover one more NT ACL invalidation case and improve comments This tries to show the difference between the cases where we trap the POSIX ACL change and where we actually detect an OS-level change. Andrew Bartlett --- source4/scripting/python/samba/tests/posixacl.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 449a87c..a575138 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -82,7 +82,7 @@ class PosixAclMappingTests(TestCase): pass os.unlink(tempf) - def test_setntacl_smbd_chmod_getntacl(self): + def test_setntacl_invalidate_getntacl(self): random.seed() lp = LoadParm() path = None @@ -103,26 +103,25 @@ class PosixAclMappingTests(TestCase): self.assertEquals(acl, facl.as_sddl(anysid)) os.unlink(tempf) - def test_setntacl_smbd_chmod_getntacl_smbd(self): + def test_setntacl_invalidate_getntacl_smbd(self): random.seed() lp = LoadParm() path = None path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This should invalidate the ACL, as we include the posix ACL in the hash (backend_obj, dbname) = checkset_backend(lp, None, None) backend_obj.wrap_setxattr(dbname, tempf, "system.fake_access_acl", "") - #the hash breaks, and we return an ACL based only on the mode + #the hash would break, and we return an ACL based only on the mode, except we set the ACL using the 'ntvfs' mode that doesn't include a hash facl = getntacl(lp,tempf) anysid = security.dom_sid(security.SID_NT_SELF) - self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) + self.assertEquals(acl, facl.as_sddl(anysid)) os.unlink(tempf) def test_setntacl_getntacl_smbd(self): @@ -163,7 +162,7 @@ class PosixAclMappingTests(TestCase): tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) open(tempf, 'w').write("empty") setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - # This invalidates the hash of the NT acl just set + # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code smbd.set_simple_acl(tempf, 0640) facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) @@ -181,7 +180,7 @@ class PosixAclMappingTests(TestCase): tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) open(tempf, 'w').write("empty") setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - # This invalidates the hash of the NT acl just set + # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code s3conf = s3param.get_context() s4_passdb = passdb.PDB(s3conf.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) -- 1.7.11.7 From 4bfca7ca4bc52c3c12e75e9d3b246222565fe43e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Oct 2012 20:17:55 +1100 Subject: [PATCH 13/42] selftest: Cover the important non-Samba invalidation of the NT ACL This covers the case where we have a valid hash of the posix ACL (or the NT ACL from the POSIX ACL) and we notice it no longer matches. Andrew Bartlett --- source4/scripting/python/samba/tests/posixacl.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index a575138..cf7a40f 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -124,6 +124,29 @@ class PosixAclMappingTests(TestCase): self.assertEquals(acl, facl.as_sddl(anysid)) os.unlink(tempf) + def test_setntacl_smbd_invalidate_getntacl_smbd(self): + random.seed() + lp = LoadParm() + path = None + path = os.environ['SELFTEST_PREFIX'] + acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x001200a9;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) + open(tempf, 'w').write("empty") + os.chmod(tempf, 0750) + setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + + # This should invalidate the ACL, as we include the posix ACL in the hash + (backend_obj, dbname) = checkset_backend(lp, None, None) + backend_obj.wrap_setxattr(dbname, + tempf, "system.fake_access_acl", "") + + #the hash will break, and we return an ACL based only on the mode + facl = getntacl(lp,tempf, direct_db_access=False) + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) + os.unlink(tempf) + def test_setntacl_getntacl_smbd(self): random.seed() lp = LoadParm() -- 1.7.11.7 From 721e846b3a57ad460e6f978a67feb4adf0fdaf69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 25 Oct 2012 20:18:28 +1100 Subject: [PATCH 14/42] selftest: Always unlink the tempf in posixacl test --- source4/scripting/python/samba/tests/posixacl.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index cf7a40f..482b48b 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -278,9 +278,11 @@ class PosixAclMappingTests(TestCase): smbd.set_simple_acl(tempf, 0750) try: facl = getntacl(lp,tempf) + self.assertTrue(False) except TypeError: # We don't expect the xattr to be filled in in this case pass + os.unlink(tempf) def test_setposixacl_getntacl_smbd(self): random.seed() @@ -294,10 +296,10 @@ class PosixAclMappingTests(TestCase): user_SID = s4_passdb.uid_to_sid(os.stat(tempf).st_uid) smbd.set_simple_acl(tempf, 0640) facl = getntacl(lp, tempf, direct_db_access=False) - domsid = passdb.get_global_sam_sid() acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) + os.unlink(tempf) def test_setposixacl_group_getntacl_smbd(self): random.seed() @@ -318,6 +320,7 @@ class PosixAclMappingTests(TestCase): acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) + os.unlink(tempf) def test_setposixacl_getposixacl(self): random.seed() -- 1.7.11.7 From 66a81f0067f011044bc5cbd7521b0726d884ff05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Oct 2012 18:23:04 +1100 Subject: [PATCH 15/42] dbwrap: use talloc_stackframe() in db_tdb_log_key() We can not be sure that there is already a talloc_stackframe() in place so we must create one. Andrew Bartlett --- lib/dbwrap/dbwrap_tdb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/dbwrap/dbwrap_tdb.c b/lib/dbwrap/dbwrap_tdb.c index 80d41b4..a3a6c87 100644 --- a/lib/dbwrap/dbwrap_tdb.c +++ b/lib/dbwrap/dbwrap_tdb.c @@ -42,10 +42,11 @@ static void db_tdb_log_key(const char *prefix, TDB_DATA key) { size_t len; char *keystr; - + TALLOC_CTX *frame; if (DEBUGLEVEL < 10) { return; } + frame = talloc_stackframe(); len = key.dsize; if (DEBUGLEVEL == 10) { /* @@ -53,10 +54,10 @@ static void db_tdb_log_key(const char *prefix, TDB_DATA key) */ len = MIN(10, key.dsize); } - keystr = hex_encode_talloc(talloc_tos(), (unsigned char *)(key.dptr), + keystr = hex_encode_talloc(frame, (unsigned char *)(key.dptr), len); DEBUG(10, ("%s key %s\n", prefix, keystr)); - TALLOC_FREE(keystr); + TALLOC_FREE(frame); } static int db_tdb_record_destr(struct db_record* data) -- 1.7.11.7 From 3e067b56309b57a3b572bff484d473114bfee0b8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 24 Oct 2012 18:24:12 +1100 Subject: [PATCH 16/42] python-ntacls: Cope with ACL revision 4 This is the new revision with the hash of the posix or system ACL. Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Thu Oct 25 15:04:39 CEST 2012 on sn-devel-104 --- source4/scripting/python/samba/ntacls.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py index 44cbbe9..f304047 100644 --- a/source4/scripting/python/samba/ntacls.py +++ b/source4/scripting/python/samba/ntacls.py @@ -78,6 +78,8 @@ def getntacl(lp, file, backend=None, eadbfile=None, direct_db_access=True): return ntacl.info.sd elif ntacl.version == 3: return ntacl.info.sd + elif ntacl.version == 4: + return ntacl.info.sd else: return smbd.get_nt_acl(file, security.SECINFO_OWNER | security.SECINFO_GROUP | security.SECINFO_DACL | security.SECINFO_SACL) -- 1.7.11.7 From 055ee4cdc970b0ced32daab76ebfca560dbf2e08 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Oct 2012 17:25:53 +1100 Subject: [PATCH 17/42] pysmbd: Add hook for unlink() so python scripts can remove xattr.tdb entries If we do not provide a way to remove files from xattr.tdb, we can re-use the inode. Andrew Bartlett --- source3/smbd/pysmbd.c | 68 ++++++++++++++++++++++++ source4/scripting/python/samba/tests/posixacl.py | 40 +++++++------- 2 files changed, 88 insertions(+), 20 deletions(-) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 5035bda..832eaeb 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -330,6 +330,71 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args) } /* + chown a file + */ +static PyObject *py_smbd_unlink(PyObject *self, PyObject *args) +{ + connection_struct *conn; + NTSTATUS status = NT_STATUS_OK; + int ret; + struct smb_filename *smb_fname = NULL; + char *fname; + int uid, gid; + TALLOC_CTX *frame; + mode_t saved_umask; + + if (!PyArg_ParseTuple(args, "s", &fname)) + return NULL; + + frame = talloc_stackframe(); + + conn = talloc_zero(frame, connection_struct); + if (conn == NULL) { + PyErr_NoMemory(); + return NULL; + } + + if (!(conn->params = talloc(conn, struct share_params))) { + PyErr_NoMemory(); + return NULL; + } + + /* we want total control over the permissions on created files, + so set our umask to 0 */ + saved_umask = umask(0); + + conn->params->service = -1; + + set_conn_connectpath(conn, "/"); + + smbd_vfs_init(conn); + + status = create_synthetic_smb_fname_split(frame, fname, NULL, + &smb_fname); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); + umask(saved_umask); + PyErr_NTSTATUS_IS_ERR_RAISE(status); + } + + ret = SMB_VFS_UNLINK(conn, smb_fname); + if (ret != 0) { + status = map_nt_error_from_unix_common(errno); + DEBUG(0,("unlink returned failure: %s\n", strerror(errno))); + } + + umask(saved_umask); + + conn_free(conn); + + TALLOC_FREE(frame); + + PyErr_NTSTATUS_IS_ERR_RAISE(status); + + Py_RETURN_NONE; +} + +/* check if we have ACL support */ static PyObject *py_smbd_have_posix_acls(PyObject *self, PyObject *args) @@ -494,6 +559,9 @@ static PyMethodDef py_smbd_methods[] = { { "chown", (PyCFunction)py_smbd_chown, METH_VARARGS, NULL }, + { "unlink", + (PyCFunction)py_smbd_unlink, METH_VARARGS, + NULL }, { NULL } }; diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 482b48b..2450470 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -45,7 +45,7 @@ class PosixAclMappingTests(TestCase): tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) open(tempf, 'w').write("empty") setntacl(lp, tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_getntacl(self): random.seed() @@ -59,7 +59,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_getntacl(self): random.seed() @@ -80,7 +80,7 @@ class PosixAclMappingTests(TestCase): self.assertTrue(False) except TypeError: pass - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_invalidate_getntacl(self): random.seed() @@ -101,7 +101,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_invalidate_getntacl_smbd(self): random.seed() @@ -122,7 +122,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_invalidate_getntacl_smbd(self): random.seed() @@ -145,7 +145,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_getntacl_smbd(self): random.seed() @@ -159,7 +159,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_getntacl_smbd(self): random.seed() @@ -173,7 +173,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_getntacl_smbd(self): random.seed() @@ -190,7 +190,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): random.seed() @@ -213,7 +213,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_smbd_getntacl_smbd_gpo(self): random.seed() @@ -227,7 +227,7 @@ class PosixAclMappingTests(TestCase): facl = getntacl(lp,tempf, direct_db_access=False) domsid = security.dom_sid("S-1-5-21-2212615479-2695158682-2101375467") self.assertEquals(facl.as_sddl(domsid),acl) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_getposixacl(self): random.seed() @@ -242,7 +242,7 @@ class PosixAclMappingTests(TestCase): anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_getposixacl(self): random.seed() @@ -266,7 +266,7 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[3].a_perm, 6) - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_getntacl(self): random.seed() @@ -282,7 +282,7 @@ class PosixAclMappingTests(TestCase): except TypeError: # We don't expect the xattr to be filled in in this case pass - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_getntacl_smbd(self): random.seed() @@ -299,7 +299,7 @@ class PosixAclMappingTests(TestCase): acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_group_getntacl_smbd(self): random.seed() @@ -320,7 +320,7 @@ class PosixAclMappingTests(TestCase): acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_getposixacl(self): random.seed() @@ -343,7 +343,7 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[3].a_perm, 6) - os.unlink(tempf) + smbd.unlink(tempf) def test_setposixacl_group_getposixacl(self): random.seed() @@ -376,7 +376,7 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[4].a_perm, 6) - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_sysvol_check_getposixacl(self): random.seed() @@ -502,7 +502,7 @@ class PosixAclMappingTests(TestCase): # - os.unlink(tempf) + smbd.unlink(tempf) def test_setntacl_policies_check_getposixacl(self): random.seed() @@ -640,7 +640,7 @@ class PosixAclMappingTests(TestCase): # - os.unlink(tempf) + smbd.unlink(tempf) def setUp(self): super(PosixAclMappingTests, self).setUp() -- 1.7.11.7 From 603eacecb04f85601c06b48abc4c2453d7305fcc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Oct 2012 10:07:02 +1100 Subject: [PATCH 18/42] pysmbd: Remember to close files after setting the NT ACL --- source3/smbd/pysmbd.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 832eaeb..a6a09d4 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -100,6 +100,9 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, set_conn_connectpath(conn, "/"); smbd_vfs_init(conn); + if (!posix_locking_init(false)) { + return NT_STATUS_NO_MEMORY; + } fsp = talloc_zero(frame, struct files_struct); if (fsp == NULL) { @@ -144,6 +147,8 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status))); } + SMB_VFS_CLOSE(fsp); + conn_free(conn); TALLOC_FREE(frame); -- 1.7.11.7 From 7d77715a8883d83d72d179036fb8e4ca9729632f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Oct 2012 14:22:07 +1100 Subject: [PATCH 19/42] pysmbd: Set umask to 0 during smbd operations --- source3/smbd/pysmbd.c | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index a6a09d4..0c8e859 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -43,6 +43,7 @@ static NTSTATUS set_sys_acl_no_snum(const char *fname, connection_struct *conn; NTSTATUS status = NT_STATUS_OK; int ret; + mode_t saved_umask; conn = talloc_zero(NULL, connection_struct); if (conn == NULL) { @@ -56,6 +57,10 @@ static NTSTATUS set_sys_acl_no_snum(const char *fname, return NT_STATUS_NO_MEMORY; } + /* we want total control over the permissions on created files, + so set our umask to 0 */ + saved_umask = umask(0); + conn->params->service = -1; set_conn_connectpath(conn, "/"); @@ -68,6 +73,8 @@ static NTSTATUS set_sys_acl_no_snum(const char *fname, DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned zero.\n")); } + umask(saved_umask); + conn_free(conn); return status; @@ -82,9 +89,16 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, files_struct *fsp; struct smb_filename *smb_fname = NULL; int flags; + mode_t saved_umask; + + if (!posix_locking_init(false)) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } conn = talloc_zero(frame, connection_struct); if (conn == NULL) { + TALLOC_FREE(frame); DEBUG(0, ("talloc failed\n")); return NT_STATUS_NO_MEMORY; } @@ -95,15 +109,6 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, return NT_STATUS_NO_MEMORY; } - conn->params->service = -1; - - set_conn_connectpath(conn, "/"); - - smbd_vfs_init(conn); - if (!posix_locking_init(false)) { - return NT_STATUS_NO_MEMORY; - } - fsp = talloc_zero(frame, struct files_struct); if (fsp == NULL) { TALLOC_FREE(frame); @@ -116,10 +121,21 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, } fsp->conn = conn; + /* we want total control over the permissions on created files, + so set our umask to 0 */ + saved_umask = umask(0); + + conn->params->service = -1; + + set_conn_connectpath(conn, "/"); + + smbd_vfs_init(conn); + status = create_synthetic_smb_fname_split(fsp, fname, NULL, &smb_fname); if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(frame); + umask(saved_umask); return status; } @@ -139,6 +155,7 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, if (fsp->fh->fd == -1) { printf("open: error=%d (%s)\n", errno, strerror(errno)); TALLOC_FREE(frame); + umask(saved_umask); return NT_STATUS_UNSUCCESSFUL; } @@ -152,6 +169,7 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, conn_free(conn); TALLOC_FREE(frame); + umask(saved_umask); return status; } @@ -296,6 +314,7 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args) char *fname; int uid, gid; TALLOC_CTX *frame; + mode_t saved_umask; if (!PyArg_ParseTuple(args, "sii", &fname, &uid, &gid)) return NULL; @@ -313,6 +332,10 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args) return NULL; } + /* we want total control over the permissions on created files, + so set our umask to 0 */ + saved_umask = umask(0); + conn->params->service = -1; set_conn_connectpath(conn, "/"); @@ -325,6 +348,8 @@ static PyObject *py_smbd_chown(PyObject *self, PyObject *args) DEBUG(0,("chown returned failure: %s\n", strerror(errno))); } + umask(saved_umask); + conn_free(conn); TALLOC_FREE(frame); -- 1.7.11.7 From 5f1392b14f2dd7ca246ff8677ac57ea2634c9fe4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Oct 2012 14:23:39 +1100 Subject: [PATCH 20/42] vfstest: set umask(0) in vfstest Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Fri Oct 26 10:07:03 CEST 2012 on sn-devel-104 --- source3/torture/vfstest.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/torture/vfstest.c b/source3/torture/vfstest.c index 72156a5..dd3787b 100644 --- a/source3/torture/vfstest.c +++ b/source3/torture/vfstest.c @@ -34,6 +34,7 @@ #include "messages.h" #include "libcli/security/security.h" #include "lib/smbd_shim.h" +#include "system/filesys.h" /* List to hold groups of commands */ static struct cmd_list { @@ -483,6 +484,10 @@ int main(int argc, char *argv[]) poptFreeContext(pc); + /* we want total control over the permissions on created files, + so set our umask to 0 */ + umask(0); + lp_load_initial_only(get_dyn_CONFIGFILE()); /* TODO: check output */ -- 1.7.11.7 From 5bf5a0639d1cf553d46e641e6e1dfa37fd600ba9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Oct 2012 09:20:52 +1100 Subject: [PATCH 21/42] provision: Fix comments in checksysvolacl --- source4/scripting/python/samba/provision/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 03d9bca..0ee621e 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -1568,8 +1568,9 @@ def checksysvolacl(samdb, netlogon, sysvol, domainsid, dnsdomain, domaindn, if domain_info["dns_domain"].upper() != dnsdomain.upper(): raise ProvisioningError('Realm as seen by pdb_samba_dsdb [%s] does not match Realm as seen by the provision script [%s]!' % (domain_info["dns_domain"].upper(), dnsdomain.upper())) - # Set the SYSVOL_ACL on the sysvol folder and subfolder (first level) + # Ensure we can read this directly, and via the smbd VFS for direct_db_access in [True, False]: + # Check the SYSVOL_ACL on the sysvol folder and subfolder (first level) for dir_path in [os.path.join(sysvol, dnsdomain), netlogon]: fsacl = getntacl(lp, dir_path, direct_db_access=direct_db_access) if fsacl is None: -- 1.7.11.7 From 25ff02b1341e0de4d2a776695cabbea7b8d1796c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Oct 2012 10:59:43 +1100 Subject: [PATCH 22/42] sefltest: use TestCaseInTempDir and setUp/tearDown for posixacl.py temp file This manages the temp file more reliably, and reduces the repeated code in each test case. Pair-Programmed-With: Jelmer Vernooij Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Sat Oct 27 04:37:58 CEST 2012 on sn-devel-104 --- source4/scripting/python/samba/tests/posixacl.py | 232 ++++++----------------- 1 file changed, 62 insertions(+), 170 deletions(-) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 2450470..5e10f8d 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -21,7 +21,7 @@ from samba.ntacls import setntacl, getntacl, checkset_backend from samba.dcerpc import xattr, security, smb_acl, idmap from samba.param import LoadParm -from samba.tests import TestCase +from samba.tests import TestCaseInTempDir from samba import provision import random import os @@ -35,224 +35,148 @@ from samba.samba3 import param as s3param # print "uid: %d" % entry.uid # print "gid: %d" % entry.gid -class PosixAclMappingTests(TestCase): +class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp, tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - smbd.unlink(tempf) + setntacl(lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) def test_setntacl_smbd_getntacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) - facl = getntacl(lp,tempf, direct_db_access=True) + setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + facl = getntacl(lp,self.tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_getntacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) # This will invalidate the ACL, as we have a hook! - smbd.set_simple_acl(tempf, 0640) + smbd.set_simple_acl(self.tempf, 0640) # However, this only asks the xattr try: - facl = getntacl(lp,tempf, direct_db_access=True) + facl = getntacl(lp, self.tempf, direct_db_access=True) self.assertTrue(False) except TypeError: pass - smbd.unlink(tempf) def test_setntacl_invalidate_getntacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) # This should invalidate the ACL, as we include the posix ACL in the hash (backend_obj, dbname) = checkset_backend(lp, None, None) backend_obj.wrap_setxattr(dbname, - tempf, "system.fake_access_acl", "") + self.tempf, "system.fake_access_acl", "") #however, as this is direct DB access, we do not notice it - facl = getntacl(lp,tempf, direct_db_access=True) + facl = getntacl(lp, self.tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setntacl_invalidate_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This should invalidate the ACL, as we include the posix ACL in the hash (backend_obj, dbname) = checkset_backend(lp, None, None) backend_obj.wrap_setxattr(dbname, - tempf, "system.fake_access_acl", "") + self.tempf, "system.fake_access_acl", "") #the hash would break, and we return an ACL based only on the mode, except we set the ACL using the 'ntvfs' mode that doesn't include a hash - facl = getntacl(lp,tempf) + facl = getntacl(lp, self.tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setntacl_smbd_invalidate_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x001200a9;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - os.chmod(tempf, 0750) - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + os.chmod(self.tempf, 0750) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This should invalidate the ACL, as we include the posix ACL in the hash (backend_obj, dbname) = checkset_backend(lp, None, None) backend_obj.wrap_setxattr(dbname, - tempf, "system.fake_access_acl", "") + self.tempf, "system.fake_access_acl", "") #the hash will break, and we return an ACL based only on the mode - facl = getntacl(lp,tempf, direct_db_access=False) + facl = getntacl(lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setntacl_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) - facl = getntacl(lp,tempf, direct_db_access=False) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + facl = getntacl(lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - smbd.unlink(tempf) def test_setntacl_smbd_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp,tempf, direct_db_access=False) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code - smbd.set_simple_acl(tempf, 0640) - facl = getntacl(lp,tempf, direct_db_access=False) + smbd.set_simple_acl(self.tempf, 0640) + facl = getntacl(lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;BA)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code s3conf = s3param.get_context() s4_passdb = passdb.PDB(s3conf.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) - smbd.set_simple_acl(tempf, 0640, BA_gid) + smbd.set_simple_acl(self.tempf, 0640, BA_gid) # This should re-calculate an ACL based on the posix details - facl = getntacl(lp,tempf, direct_db_access=False) + facl = getntacl(lp,self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setntacl_smbd_getntacl_smbd_gpo(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:DAG:DUD:P(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;EA)(A;OICIIO;0x001f01ff;;;CO)(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001200a9;;;ED)S:AI(OU;CIIDSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)(OU;CIIDSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp,tempf, direct_db_access=False) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(lp, self.tempf, direct_db_access=False) domsid = security.dom_sid("S-1-5-21-2212615479-2695158682-2101375467") self.assertEquals(facl.as_sddl(domsid),acl) - smbd.unlink(tempf) def test_setntacl_getposixacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp,tempf) + setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(lp, self.tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) - smbd.unlink(tempf) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) def test_setposixacl_getposixacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - smbd.set_simple_acl(tempf, 0640) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + smbd.set_simple_acl(self.tempf, 0640) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 4) self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) @@ -266,70 +190,50 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[3].a_perm, 6) - smbd.unlink(tempf) def test_setposixacl_getntacl(self): - random.seed() lp = LoadParm() acl = "" - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - smbd.set_simple_acl(tempf, 0750) + smbd.set_simple_acl(self.tempf, 0750) try: - facl = getntacl(lp,tempf) + facl = getntacl(lp, self.tempf) self.assertTrue(False) except TypeError: # We don't expect the xattr to be filled in in this case pass - smbd.unlink(tempf) def test_setposixacl_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") s3conf = s3param.get_context() s4_passdb = passdb.PDB(s3conf.get("passdb backend")) - group_SID = s4_passdb.gid_to_sid(os.stat(tempf).st_gid) - user_SID = s4_passdb.uid_to_sid(os.stat(tempf).st_uid) - smbd.set_simple_acl(tempf, 0640) - facl = getntacl(lp, tempf, direct_db_access=False) + group_SID = s4_passdb.gid_to_sid(os.stat(self.tempf).st_gid) + user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) + smbd.set_simple_acl(self.tempf, 0640) + facl = getntacl(lp, self.tempf, direct_db_access=False) acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setposixacl_group_getntacl_smbd(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) s3conf = s3param.get_context() s4_passdb = passdb.PDB(s3conf.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) - group_SID = s4_passdb.gid_to_sid(os.stat(tempf).st_gid) - user_SID = s4_passdb.uid_to_sid(os.stat(tempf).st_uid) + group_SID = s4_passdb.gid_to_sid(os.stat(self.tempf).st_gid) + user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) - smbd.set_simple_acl(tempf, 0640, BA_gid) - facl = getntacl(lp, tempf, direct_db_access=False) + smbd.set_simple_acl(self.tempf, 0640, BA_gid) + facl = getntacl(lp, self.tempf, direct_db_access=False) domsid = passdb.get_global_sam_sid() acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) - smbd.unlink(tempf) def test_setposixacl_getposixacl(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - smbd.set_simple_acl(tempf, 0640) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + smbd.set_simple_acl(self.tempf, 0640) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 4) self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) @@ -343,21 +247,16 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[3].a_perm, 6) - smbd.unlink(tempf) def test_setposixacl_group_getposixacl(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) s3conf = s3param.get_context() s4_passdb = passdb.PDB(s3conf.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) - smbd.set_simple_acl(tempf, 0670, BA_gid) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + smbd.set_simple_acl(self.tempf, 0670, BA_gid) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 5) @@ -376,22 +275,16 @@ class PosixAclMappingTests(TestCase): self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[4].a_perm, 6) - smbd.unlink(tempf) def test_setntacl_sysvol_check_getposixacl(self): - random.seed() lp = LoadParm() s3conf = s3param.get_context() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = provision.SYSVOL_ACL - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") domsid = passdb.get_global_sam_sid() - setntacl(lp,tempf,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp,tempf) + setntacl(lp, self.tempf,acl,str(domsid), use_ntvfs=False) + facl = getntacl(lp, self.tempf) self.assertEquals(facl.as_sddl(domsid),acl) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) LA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_ADMINISTRATOR)) BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) @@ -502,22 +395,17 @@ class PosixAclMappingTests(TestCase): # - smbd.unlink(tempf) def test_setntacl_policies_check_getposixacl(self): - random.seed() lp = LoadParm() s3conf = s3param.get_context() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = provision.POLICIES_ACL - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") + domsid = passdb.get_global_sam_sid() - setntacl(lp,tempf,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp,tempf) + setntacl(lp, self.tempf,acl,str(domsid), use_ntvfs=False) + facl = getntacl(lp, self.tempf) self.assertEquals(facl.as_sddl(domsid),acl) - posix_acl = smbd.get_sys_acl(tempf, smb_acl.SMB_ACL_TYPE_ACCESS) + posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) LA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_ADMINISTRATOR)) BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) @@ -640,9 +528,13 @@ class PosixAclMappingTests(TestCase): # - smbd.unlink(tempf) - def setUp(self): super(PosixAclMappingTests, self).setUp() s3conf = s3param.get_context() s3conf.load(self.get_loadparm().configfile) + self.tempf = os.path.join(self.tempdir, "test") + open(self.tempf, 'w').write("empty") + + def tearDown(self): + smbd.unlink(self.tempf) + super(PosixAclMappingTests, self).tearDown() -- 1.7.11.7 From a41aad222eb613d3469e500fcc7f85dcbe8fd6a3 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 26 Oct 2012 15:58:06 -0800 Subject: [PATCH 23/42] TestCaseInTempDir: Use addCleanup rather than tearDown. --- source4/scripting/python/samba/tests/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/tests/__init__.py b/source4/scripting/python/samba/tests/__init__.py index b13bcab..2df30a6 100644 --- a/source4/scripting/python/samba/tests/__init__.py +++ b/source4/scripting/python/samba/tests/__init__.py @@ -76,11 +76,12 @@ class TestCaseInTempDir(TestCase): def setUp(self): super(TestCaseInTempDir, self).setUp() self.tempdir = tempfile.mkdtemp() + self.addCleanup(self._remove_tempdir) - def tearDown(self): - super(TestCaseInTempDir, self).tearDown() + def _remove_tempdir(self): self.assertEquals([], os.listdir(self.tempdir)) os.rmdir(self.tempdir) + self.tempdir = None def env_loadparm(): -- 1.7.11.7 From 07b599389a9184c219d05dc04ce4a2cd52e1cd72 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 1 Nov 2012 09:51:28 +1100 Subject: [PATCH 24/42] vfs_acl_common: In add_directory_inheritable_components allocate on psd as parent When we add a new DACL to the security descriptor, we need to use the SD as the memory context, so we can talloc_move() it as a tree to a new parent. Andrew Bartlett Signed-off-by: Andrew Bartlett Reviewed by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Fri Nov 2 22:16:14 CET 2012 on sn-devel-104 --- source3/modules/vfs_acl_common.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index ef2dda1..59ced29 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -195,9 +195,21 @@ static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle, mode_t dir_mode; mode_t file_mode; mode_t mode; - struct security_ace *new_ace_list = talloc_zero_array(talloc_tos(), - struct security_ace, - num_aces + 3); + struct security_ace *new_ace_list; + + if (psd->dacl) { + new_ace_list = talloc_zero_array(psd->dacl, + struct security_ace, + num_aces + 3); + } else { + /* + * make_sec_acl() at the bottom of this function + * dupliates new_ace_list + */ + new_ace_list = talloc_zero_array(talloc_tos(), + struct security_ace, + num_aces + 3); + } if (new_ace_list == NULL) { return NT_STATUS_NO_MEMORY; @@ -256,7 +268,7 @@ static NTSTATUS add_directory_inheritable_components(vfs_handle_struct *handle, psd->dacl->aces = new_ace_list; psd->dacl->num_aces += 3; } else { - psd->dacl = make_sec_acl(talloc_tos(), + psd->dacl = make_sec_acl(psd, NT4_ACL_REVISION, 3, new_ace_list); -- 1.7.11.7 From dedafd24ebb17d4f686109e07e13ef61d771d28a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Nov 2012 12:57:17 +1100 Subject: [PATCH 25/42] selftest: check that samba-tool gpo works for basic operations Reviewed-by: Jelmer Vernooij Signed-off-by: Andrew Bartlett --- selftest/target/Samba4.pm | 2 +- .../scripting/python/samba/tests/samba_tool/gpo.py | 57 ++++++++++++++++++++++ source4/selftest/tests.py | 7 +++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 source4/scripting/python/samba/tests/samba_tool/gpo.py diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index fbc8117..20114c9 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -799,7 +799,7 @@ sub provision($$$$$$$$$) [sysvol] path = $ctx->{statedir}/sysvol - read only = yes + read only = no [netlogon] path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts diff --git a/source4/scripting/python/samba/tests/samba_tool/gpo.py b/source4/scripting/python/samba/tests/samba_tool/gpo.py new file mode 100644 index 0000000..84154f5 --- /dev/null +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -0,0 +1,57 @@ +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Bartlett 2012 +# +# based on time.py: +# Copyright (C) Sean Dague 2011 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +import os +from samba.tests.samba_tool.base import SambaToolCmdTest + +class GpoCmdTestCase(SambaToolCmdTest): + """Tests for samba-tool time subcommands""" + + gpo_name = "testgpo" + + def test_gpo_list(self): + """Run gpo list against the server and make sure it looks accurate""" + (result, out, err) = self.runsubcmd("gpo", "listall", "-H", "ldap://%s" % os.environ["SERVER"]) + self.assertCmdSuccess(result, "Ensuring gpo listall ran successfully") + + def test_fetchfail(self): + """Run against a non-existent GPO, and make sure it fails (this hard-coded UUID is very unlikely to exist""" + (result, out, err) = self.runsubcmd("gpo", "fetch", "c25cac17-a02a-4151-835d-fae17446ee43", "-H", "ldap://%s" % +os.environ["SERVER"]) + self.assertEquals(result, -1, "check for result code") + + def test_fetch(self): + """Run against a real GPO, and make sure it passes""" + (result, out, err) = self.runsubcmd("gpo", "fetch", self.gpo_guid, "-H", "ldap://%s" % os.environ["SERVER"], "--tmpdir", os.environ['SELFTEST_PREFIX']) + self.assertCmdSuccess(result, "Ensuring gpo fetched successfully") + + def setUp(self): + """set up a temporary GPO to work with""" + super(GpoCmdTestCase, self).setUp() + (result, out, err) = self.runsubcmd("gpo", "create", self.gpo_name, "-H", "ldap://%s" % os.environ["SERVER"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) + self.gpo_guid = "{%s}" % out.split("{")[1].split("}")[0] + + self.assertCmdSuccess(result, "Ensuring gpo created successfully") + + def tearDown(self): + """remove the temporary GPO to work with""" + (result, out, err) = self.runsubcmd("gpo", "del", self.gpo_guid, "-H", "ldap://%s" % os.environ["SERVER"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) + self.assertCmdSuccess(result, "Ensuring gpo deleted successfully") + super(GpoCmdTestCase, self).tearDown() diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py index ea09071..2173807 100755 --- a/source4/selftest/tests.py +++ b/source4/selftest/tests.py @@ -405,6 +405,13 @@ planpythontestsuite("dc:local", "samba.tests.dcerpc.bare") planpythontestsuite("dc:local", "samba.tests.dcerpc.unix") planpythontestsuite("dc:local", "samba.tests.dcerpc.srvsvc") planpythontestsuite("dc:local", "samba.tests.samba_tool.timecmd") + +# We run this test against both AD DC implemetnations because it is +# the only test we have of GPO get/set behaviour, and this involves +# the file server as well as the LDAP server. +planpythontestsuite("dc:local", "samba.tests.samba_tool.gpo") +planpythontestsuite("plugin_s4_dc:local", "samba.tests.samba_tool.gpo") + planpythontestsuite("dc:local", "samba.tests.samba_tool.user") planpythontestsuite("dc:local", "samba.tests.samba_tool.group") planpythontestsuite("plugin_s4_dc:local", "samba.tests.samba_tool.ntacl") -- 1.7.11.7 From 6cdc28ff3273a9c8dc54e1e7a32615c124012498 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Nov 2012 15:22:02 +1100 Subject: [PATCH 26/42] provision: Also walk directories checking ACLs The directory walk was missed due to a cut-and-paste error. Andrew Bartlett Reviewed-by: Jelmer Vernooij Signed-off-by: Andrew Bartlett --- source4/scripting/python/samba/provision/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index 0ee621e..e2bb1b9 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -1493,7 +1493,7 @@ def check_dir_acl(path, acl, lp, domainsid, direct_db_access): if fsacl_sddl != acl: raise ProvisioningError('%s ACL on GPO file %s %s does not match expected value %s from GPO object' % (acl_type(direct_db_access), os.path.join(root, name), fsacl_sddl, acl)) - for name in files: + for name in dirs: fsacl = getntacl(lp, os.path.join(root, name), direct_db_access=direct_db_access) if fsacl is None: raise ProvisioningError('%s ACL on GPO directory %s %s not found!' % (acl_type(direct_db_access), os.path.join(root, name))) -- 1.7.11.7 From 65756a64ce22f6460988f8a7e27fcd298e645546 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Nov 2012 20:44:14 +1100 Subject: [PATCH 27/42] provision: Make dsacl2fsacl() take a security.dom_sid, not str Reviewed-by: Jelmer Vernooij Signed-off-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Tue Nov 6 00:12:43 CET 2012 on sn-devel-104 --- source4/scripting/python/samba/netcmd/gpo.py | 4 ++-- source4/scripting/python/samba/ntacls.py | 3 +-- source4/scripting/python/samba/provision/__init__.py | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 53bfcaa..347231b 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -975,9 +975,9 @@ class cmd_create(Command): ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl() # Create a file system security descriptor - domain_sid = self.samdb.get_domain_sid() + domain_sid = security.dom_sid(self.samdb.get_domain_sid()) sddl = dsacl2fsacl(ds_sd, domain_sid) - fs_sd = security.descriptor.from_sddl(sddl, security.dom_sid(domain_sid)) + fs_sd = security.descriptor.from_sddl(sddl, domain_sid) # Set ACL sio = ( security.SECINFO_OWNER | diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py index f304047..89d450a 100644 --- a/source4/scripting/python/samba/ntacls.py +++ b/source4/scripting/python/samba/ntacls.py @@ -198,14 +198,13 @@ def ldapmask2filemask(ldm): return filemask -def dsacl2fsacl(dssddl, domsid): +def dsacl2fsacl(dssddl, sid): """ This function takes an the SDDL representation of a DS ACL and return the SDDL representation of this ACL adapted for files. It's used for Policy object provision """ - sid = security.dom_sid(domsid) ref = security.descriptor.from_sddl(dssddl, sid) fdescr = security.descriptor() fdescr.owner_sid = ref.owner_sid diff --git a/source4/scripting/python/samba/provision/__init__.py b/source4/scripting/python/samba/provision/__init__.py index e2bb1b9..10afda0 100644 --- a/source4/scripting/python/samba/provision/__init__.py +++ b/source4/scripting/python/samba/provision/__init__.py @@ -1404,7 +1404,7 @@ def set_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, use_ntvfs, p acl = ndr_unpack(security.descriptor, str(policy["nTSecurityDescriptor"])).as_sddl() policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) - set_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp, + set_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, str(domainsid), use_ntvfs, passdb=passdb) @@ -1531,7 +1531,7 @@ def check_gpos_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp, acl = ndr_unpack(security.descriptor, str(policy["nTSecurityDescriptor"])).as_sddl() policy_path = getpolicypath(sysvol, dnsdomain, str(policy["cn"])) - check_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp, + check_dir_acl(policy_path, dsacl2fsacl(acl, domainsid), lp, domainsid, direct_db_access) -- 1.7.11.7 From a147660a556a0264db11d07e0ec7a7c7ce571873 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2012 11:35:02 +1100 Subject: [PATCH 28/42] samba-tool: Rework ldap attribute fetch in classicupgrade for missing attributes Is is not required that these additional attributes be filled in, so catch KeyError in both the nsswitch and ldap backend case. We rework get_posix_attr_from_ldap_backend() so it raises KeyError rather than trying to return None, and does not ignore other errors. Andrew Bartlett Tested-by: Chirana Gheorghita Eugeniu Theodor Signed-off-by: Andrew Bartlett Reviewed-by: Jelmer Vernooij --- source4/scripting/python/samba/upgrade.py | 41 ++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/source4/scripting/python/samba/upgrade.py b/source4/scripting/python/samba/upgrade.py index 786bb65..13d33c1 100644 --- a/source4/scripting/python/samba/upgrade.py +++ b/source4/scripting/python/samba/upgrade.py @@ -539,13 +539,14 @@ def get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, user, attr): expression=("(&(objectClass=posixAccount)(uid=%s))" % (user)), attrs=[attr]) except ldb.LdbError, e: - logger.warning("Failed to retrieve attribute %s for user %s, the error is: %s", attr, user, e) + raise ProvisioningError("Failed to retrieve attribute %s for user %s, the error is: %s", attr, user, e) else: - if msg.count == 1: + if msg.count <= 1: + # This will raise KeyError (which is what we want) if there isn't a entry for this user return msg[0][attr][0] else: logger.warning("LDAP entry for user %s contains more than one %s", user, attr) - return None + raise KeyError def upgrade_from_samba3(samba3, logger, targetdir, session_info=None, @@ -794,23 +795,29 @@ Please fix this account before attempting to upgrade again for entry in userlist: username = entry['account_name'] if username in uids.keys(): - if ldap: - homes[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "homeDirectory") - shells[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "loginShell") - pgids[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "gidNumber") - else: - try: + try: + if ldap: + homes[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "homeDirectory") + else: homes[username] = pwd.getpwnam(username).pw_dir - except KeyError: - pass - try: + except KeyError: + pass + + try: + if ldap: + shells[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "loginShell") + else: shells[username] = pwd.getpwnam(username).pw_shell - except KeyError: - pass - try: + except KeyError: + pass + + try: + if ldap: + pgids[username] = get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, username, "gidNumber") + else: pgids[username] = pwd.getpwnam(username).pw_gid - except KeyError: - pass + except KeyError: + pass logger.info("Reading WINS database") samba3_winsdb = None -- 1.7.11.7 From 9c14d375f1a80fee24a5a608f8dd8f92e15ceafb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2012 14:01:44 +1100 Subject: [PATCH 29/42] selftest: Make samba.tests.ntacl also use TestCaseInTempDir This follows on from the successful conversion of samba.tests.posixacl. Andrew Bartlett Signed-off-by: Andrew Bartlett Reviewed-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett --- source4/scripting/python/samba/tests/ntacls.py | 68 ++++++++++++-------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/source4/scripting/python/samba/tests/ntacls.py b/source4/scripting/python/samba/tests/ntacls.py index 8cdf613..aa9ef68 100644 --- a/source4/scripting/python/samba/tests/ntacls.py +++ b/source4/scripting/python/samba/tests/ntacls.py @@ -1,5 +1,6 @@ # Unix SMB/CIFS implementation. Tests for ntacls manipulation # Copyright (C) Matthieu Patou 2009-2010 +# Copyright (C) Andrew Bartlett 2012 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -20,70 +21,63 @@ from samba.ntacls import setntacl, getntacl, XattrBackendError from samba.dcerpc import xattr, security from samba.param import LoadParm -from samba.tests import TestCase, TestSkipped +from samba.tests import TestCaseInTempDir, TestSkipped import random import os -class NtaclsTests(TestCase): +class NtaclsTests(TestCaseInTempDir): def test_setntacl(self): - random.seed() lp = LoadParm() - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - lp.set("posix:eadb",os.path.join(path,"eadbtest.tdb")) - setntacl(lp, tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467") - os.unlink(tempf) + open(self.tempf, 'w').write("empty") + lp.set("posix:eadb",os.path.join(self.tempdir,"eadbtest.tdb")) + setntacl(lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467") + os.unlink(os.path.join(self.tempdir,"eadbtest.tdb")) def test_setntacl_getntacl(self): - random.seed() lp = LoadParm() - path = None - path = os.environ['SELFTEST_PREFIX'] acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - lp.set("posix:eadb",os.path.join(path,"eadbtest.tdb")) - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467") - facl = getntacl(lp,tempf) + open(self.tempf, 'w').write("empty") + lp.set("posix:eadb",os.path.join(self.tempdir,"eadbtest.tdb")) + setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467") + facl = getntacl(lp,self.tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) - os.unlink(tempf) + os.unlink(os.path.join(self.tempdir,"eadbtest.tdb")) def test_setntacl_getntacl_param(self): - random.seed() lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - setntacl(lp,tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467","tdb",os.path.join(path,"eadbtest.tdb")) - facl=getntacl(lp,tempf,"tdb",os.path.join(path,"eadbtest.tdb")) + open(self.tempf, 'w').write("empty") + setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467","tdb",os.path.join(self.tempdir,"eadbtest.tdb")) + facl=getntacl(lp,self.tempf,"tdb",os.path.join(self.tempdir,"eadbtest.tdb")) domsid=security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(domsid),acl) - os.unlink(tempf) + os.unlink(os.path.join(self.tempdir,"eadbtest.tdb")) def test_setntacl_invalidbackend(self): - random.seed() lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - self.assertRaises(XattrBackendError, setntacl, lp, tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467","ttdb", os.path.join(path,"eadbtest.tdb")) + open(self.tempf, 'w').write("empty") + self.assertRaises(XattrBackendError, setntacl, lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467","ttdb", os.path.join(self.tempdir,"eadbtest.tdb")) def test_setntacl_forcenative(self): if os.getuid() == 0: raise TestSkipped("Running test as root, test skipped") - random.seed() lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - path = os.environ['SELFTEST_PREFIX'] - tempf = os.path.join(path,"pytests"+str(int(100000*random.random()))) - open(tempf, 'w').write("empty") - lp.set("posix:eadb", os.path.join(path,"eadbtest.tdb")) - self.assertRaises(Exception, setntacl, lp, tempf ,acl, + open(self.tempf, 'w').write("empty") + lp.set("posix:eadb", os.path.join(self.tempdir,"eadbtest.tdb")) + self.assertRaises(Exception, setntacl, lp, self.tempf ,acl, "S-1-5-21-2212615479-2695158682-2101375467","native") - os.unlink(tempf) + + + def setUp(self): + super(NtaclsTests, self).setUp() + self.tempf = os.path.join(self.tempdir, "test") + open(self.tempf, 'w').write("empty") + + def tearDown(self): + os.unlink(self.tempf) + super(NtaclsTests, self).tearDown() -- 1.7.11.7 From 683b230fddb8b84f7731949ddacc87e1347d85a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2012 22:07:49 +1100 Subject: [PATCH 30/42] pysmbd: Add SMB_ACL_EXECUTE to the mask set by make_simple_acl() Signed-off-by: Andrew Bartlett Reviewed-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett --- source3/smbd/pysmbd.c | 2 +- source4/scripting/python/samba/tests/posixacl.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 0c8e859..1489355 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -178,7 +178,7 @@ static SMB_ACL_T make_simple_acl(gid_t gid, mode_t chmod_mode) { TALLOC_CTX *frame = talloc_stackframe(); - mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE; + mode_t mode = SMB_ACL_READ|SMB_ACL_WRITE|SMB_ACL_EXECUTE; mode_t mode_user = (chmod_mode & 0700) >> 6; mode_t mode_group = (chmod_mode & 070) >> 3; diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 5e10f8d..50518f0 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -246,7 +246,7 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[2].a_perm, 0) self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) - self.assertEquals(posix_acl.acl[3].a_perm, 6) + self.assertEquals(posix_acl.acl[3].a_perm, 7) def test_setposixacl_group_getposixacl(self): lp = LoadParm() @@ -274,7 +274,7 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[3].info.gid, BA_gid) self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_MASK) - self.assertEquals(posix_acl.acl[4].a_perm, 6) + self.assertEquals(posix_acl.acl[4].a_perm, 7) def test_setntacl_sysvol_check_getposixacl(self): lp = LoadParm() -- 1.7.11.7 From dac0e4479055bda72fc162844471665025c84875 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2012 21:33:41 +1100 Subject: [PATCH 31/42] selftest: Add tests for expected behaviour on directories as well as files This is important because it covers the codepath which had the talloc error fixed by commit 60cf4cb5a630506747431ecbf00d890509baf2f3 (vfs_acl_common: In add_directory_inheritable_components allocate on psd as parent) Andrew Bartlett Signed-off-by: Andrew Bartlett Reviewed-by: Jelmer Vernooij Reviewed-by: Andrew Bartlett Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Sun Nov 11 15:48:10 CET 2012 on sn-devel-104 --- source4/scripting/python/samba/tests/posixacl.py | 197 +++++++++++++++++++++++ 1 file changed, 197 insertions(+) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 50518f0..9df904b 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -214,6 +214,18 @@ class PosixAclMappingTests(TestCaseInTempDir): anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) + def test_setposixacl_dir_getntacl_smbd(self): + lp = LoadParm() + s3conf = s3param.get_context() + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + user_SID = s4_passdb.uid_to_sid(os.stat(self.tempdir).st_uid) + smbd.set_simple_acl(self.tempdir, 0750) + facl = getntacl(lp, self.tempdir, direct_db_access=False) + acl = "O:%sG:BAD:(A;;0x001f01ff;;;%s)(A;;0x001200a9;;;BA)(A;;WO;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001f01ff;;;CG)(A;OICIIO;0x001f01ff;;;WD)" % (user_SID, user_SID) + + anysid = security.dom_sid(security.SID_NT_SELF) + self.assertEquals(acl, facl.as_sddl(anysid)) + def test_setposixacl_group_getntacl_smbd(self): lp = LoadParm() BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) @@ -248,6 +260,24 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) self.assertEquals(posix_acl.acl[3].a_perm, 7) + def test_setposixacl_dir_getposixacl(self): + lp = LoadParm() + smbd.set_simple_acl(self.tempdir, 0750) + posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) + self.assertEquals(posix_acl.count, 4) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[0].a_perm, 7) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[1].a_perm, 5) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[3].a_perm, 7) + def test_setposixacl_group_getposixacl(self): lp = LoadParm() BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) @@ -396,6 +426,173 @@ class PosixAclMappingTests(TestCaseInTempDir): # + def test_setntacl_sysvol_dir_check_getposixacl(self): + lp = LoadParm() + s3conf = s3param.get_context() + acl = provision.SYSVOL_ACL + domsid = passdb.get_global_sam_sid() + setntacl(lp, self.tempdir,acl,str(domsid), use_ntvfs=False) + facl = getntacl(lp, self.tempdir) + self.assertEquals(facl.as_sddl(domsid),acl) + posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) + + LA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_ADMINISTRATOR)) + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + SO_sid = security.dom_sid(security.SID_BUILTIN_SERVER_OPERATORS) + SY_sid = security.dom_sid(security.SID_NT_SYSTEM) + AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) + + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + + # These assertions correct for current plugin_s4_dc selftest + # configuration. When other environments have a broad range of + # groups mapped via passdb, we can relax some of these checks + (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid) + self.assertEquals(LA_type, idmap.ID_TYPE_UID) + (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) + self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) + (SO_gid,SO_type) = s4_passdb.sid_to_id(SO_sid) + self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) + (SY_gid,SY_type) = s4_passdb.sid_to_id(SY_sid) + self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) + (AU_gid,AU_type) = s4_passdb.sid_to_id(AU_sid) + self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) + + self.assertEquals(posix_acl.count, 9) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[0].a_perm, 7) + self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) + self.assertEquals(posix_acl.acl[1].a_perm, 7) + self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[3].a_perm, 7) + + self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[4].a_perm, 7) + + self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[5].a_perm, 5) + self.assertEquals(posix_acl.acl[5].info.gid, SO_gid) + + self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[6].a_perm, 7) + self.assertEquals(posix_acl.acl[6].info.gid, SY_gid) + + self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[7].a_perm, 5) + self.assertEquals(posix_acl.acl[7].info.gid, AU_gid) + + self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[8].a_perm, 7) + + +# check that it matches: +# user::rwx +# user:root:rwx (selftest user actually) +# group::rwx +# group:3000000:rwx +# group:3000001:r-x +# group:3000002:rwx +# group:3000003:r-x +# mask::rwx +# other::--- + + + def test_setntacl_policies_dir_check_getposixacl(self): + lp = LoadParm() + s3conf = s3param.get_context() + acl = provision.POLICIES_ACL + domsid = passdb.get_global_sam_sid() + setntacl(lp, self.tempdir,acl,str(domsid), use_ntvfs=False) + facl = getntacl(lp, self.tempdir) + self.assertEquals(facl.as_sddl(domsid),acl) + posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) + + LA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_ADMINISTRATOR)) + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + SO_sid = security.dom_sid(security.SID_BUILTIN_SERVER_OPERATORS) + SY_sid = security.dom_sid(security.SID_NT_SYSTEM) + AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) + PA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_POLICY_ADMINS)) + + s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + + # These assertions correct for current plugin_s4_dc selftest + # configuration. When other environments have a broad range of + # groups mapped via passdb, we can relax some of these checks + (LA_uid,LA_type) = s4_passdb.sid_to_id(LA_sid) + self.assertEquals(LA_type, idmap.ID_TYPE_UID) + (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) + self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) + (SO_gid,SO_type) = s4_passdb.sid_to_id(SO_sid) + self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) + (SY_gid,SY_type) = s4_passdb.sid_to_id(SY_sid) + self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) + (AU_gid,AU_type) = s4_passdb.sid_to_id(AU_sid) + self.assertEquals(AU_type, idmap.ID_TYPE_BOTH) + (PA_gid,PA_type) = s4_passdb.sid_to_id(PA_sid) + self.assertEquals(PA_type, idmap.ID_TYPE_BOTH) + + self.assertEquals(posix_acl.count, 10) + + self.assertEquals(posix_acl.acl[0].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[0].a_perm, 7) + self.assertEquals(posix_acl.acl[0].info.gid, BA_gid) + + self.assertEquals(posix_acl.acl[1].a_type, smb_acl.SMB_ACL_USER) + self.assertEquals(posix_acl.acl[1].a_perm, 7) + self.assertEquals(posix_acl.acl[1].info.uid, LA_uid) + + self.assertEquals(posix_acl.acl[2].a_type, smb_acl.SMB_ACL_OTHER) + self.assertEquals(posix_acl.acl[2].a_perm, 0) + + self.assertEquals(posix_acl.acl[3].a_type, smb_acl.SMB_ACL_USER_OBJ) + self.assertEquals(posix_acl.acl[3].a_perm, 7) + + self.assertEquals(posix_acl.acl[4].a_type, smb_acl.SMB_ACL_GROUP_OBJ) + self.assertEquals(posix_acl.acl[4].a_perm, 7) + + self.assertEquals(posix_acl.acl[5].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[5].a_perm, 5) + self.assertEquals(posix_acl.acl[5].info.gid, SO_gid) + + self.assertEquals(posix_acl.acl[6].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[6].a_perm, 7) + self.assertEquals(posix_acl.acl[6].info.gid, SY_gid) + + self.assertEquals(posix_acl.acl[7].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[7].a_perm, 5) + self.assertEquals(posix_acl.acl[7].info.gid, AU_gid) + + self.assertEquals(posix_acl.acl[8].a_type, smb_acl.SMB_ACL_GROUP) + self.assertEquals(posix_acl.acl[8].a_perm, 7) + self.assertEquals(posix_acl.acl[8].info.gid, PA_gid) + + self.assertEquals(posix_acl.acl[9].a_type, smb_acl.SMB_ACL_MASK) + self.assertEquals(posix_acl.acl[9].a_perm, 7) + + +# check that it matches: +# user::rwx +# user:root:rwx (selftest user actually) +# group::rwx +# group:3000000:rwx +# group:3000001:r-x +# group:3000002:rwx +# group:3000003:r-x +# group:3000004:rwx +# mask::rwx +# other::--- + + + def test_setntacl_policies_check_getposixacl(self): lp = LoadParm() s3conf = s3param.get_context() -- 1.7.11.7 From 4bc0ffc4044af46ae3fb270913a2231a7bacfed6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Nov 2012 07:53:40 +1100 Subject: [PATCH 32/42] selftest: Avoid test cross-contamination in samba.tests.posixacl This creates a new xattr.tdb per unit test, which avoids once and for all the issue of dev/inode reuse. For test_setposixacl_dir_getntacl_smbd the file ownership also set specifically. Andrew Bartlett Reviewed-by: Jelmer Vernooij --- source4/scripting/python/samba/tests/posixacl.py | 140 ++++++++++------------- 1 file changed, 59 insertions(+), 81 deletions(-) diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index 9df904b..f949ab4 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -38,143 +38,129 @@ from samba.samba3 import param as s3param class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) def test_setntacl_smbd_getntacl(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) - facl = getntacl(lp,self.tempf, direct_db_access=True) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + facl = getntacl(self.lp, self.tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) def test_setntacl_smbd_setposixacl_getntacl(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) # This will invalidate the ACL, as we have a hook! smbd.set_simple_acl(self.tempf, 0640) # However, this only asks the xattr try: - facl = getntacl(lp, self.tempf, direct_db_access=True) + facl = getntacl(self.lp, self.tempf, direct_db_access=True) self.assertTrue(False) except TypeError: pass def test_setntacl_invalidate_getntacl(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) # This should invalidate the ACL, as we include the posix ACL in the hash - (backend_obj, dbname) = checkset_backend(lp, None, None) + (backend_obj, dbname) = checkset_backend(self.lp, None, None) backend_obj.wrap_setxattr(dbname, self.tempf, "system.fake_access_acl", "") #however, as this is direct DB access, we do not notice it - facl = getntacl(lp, self.tempf, direct_db_access=True) + facl = getntacl(self.lp, self.tempf, direct_db_access=True) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) def test_setntacl_invalidate_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This should invalidate the ACL, as we include the posix ACL in the hash - (backend_obj, dbname) = checkset_backend(lp, None, None) + (backend_obj, dbname) = checkset_backend(self.lp, None, None) backend_obj.wrap_setxattr(dbname, self.tempf, "system.fake_access_acl", "") #the hash would break, and we return an ACL based only on the mode, except we set the ACL using the 'ntvfs' mode that doesn't include a hash - facl = getntacl(lp, self.tempf) + facl = getntacl(self.lp, self.tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) def test_setntacl_smbd_invalidate_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x001200a9;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" os.chmod(self.tempf, 0750) - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This should invalidate the ACL, as we include the posix ACL in the hash - (backend_obj, dbname) = checkset_backend(lp, None, None) + (backend_obj, dbname) = checkset_backend(self.lp, None, None) backend_obj.wrap_setxattr(dbname, self.tempf, "system.fake_access_acl", "") #the hash will break, and we return an ACL based only on the mode - facl = getntacl(lp, self.tempf, direct_db_access=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) def test_setntacl_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) - facl = getntacl(lp, self.tempf, direct_db_access=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=True) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) def test_setntacl_smbd_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp, self.tempf, direct_db_access=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) def test_setntacl_smbd_setposixacl_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code smbd.set_simple_acl(self.tempf, 0640) - facl = getntacl(lp, self.tempf, direct_db_access=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;BA)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" - setntacl(lp,self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code - s3conf = s3param.get_context() - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) smbd.set_simple_acl(self.tempf, 0640, BA_gid) # This should re-calculate an ACL based on the posix details - facl = getntacl(lp,self.tempf, direct_db_access=False) + facl = getntacl(self.lp,self.tempf, direct_db_access=False) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(simple_acl_from_posix, facl.as_sddl(anysid)) def test_setntacl_smbd_getntacl_smbd_gpo(self): - lp = LoadParm() acl = "O:DAG:DUD:P(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;EA)(A;OICIIO;0x001f01ff;;;CO)(A;OICI;0x001f01ff;;;DA)(A;OICI;0x001f01ff;;;SY)(A;OICI;0x001200a9;;;AU)(A;OICI;0x001200a9;;;ED)S:AI(OU;CIIDSA;WP;f30e3bbe-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)(OU;CIIDSA;WP;f30e3bbf-9ff0-11d1-b603-0000f80367c1;bf967aa5-0de6-11d0-a285-00aa003049e2;WD)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp, self.tempf, direct_db_access=False) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) domsid = security.dom_sid("S-1-5-21-2212615479-2695158682-2101375467") self.assertEquals(facl.as_sddl(domsid),acl) def test_setntacl_getposixacl(self): - lp = LoadParm() acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - setntacl(lp, self.tempf,acl,"S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) - facl = getntacl(lp, self.tempf) + setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) + facl = getntacl(self.lp, self.tempf) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(facl.as_sddl(anysid),acl) posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) def test_setposixacl_getposixacl(self): - lp = LoadParm() smbd.set_simple_acl(self.tempf, 0640) posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 4) @@ -192,58 +178,58 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[3].a_perm, 6) def test_setposixacl_getntacl(self): - lp = LoadParm() acl = "" smbd.set_simple_acl(self.tempf, 0750) try: - facl = getntacl(lp, self.tempf) + facl = getntacl(self.lp, self.tempf) self.assertTrue(False) except TypeError: # We don't expect the xattr to be filled in in this case pass def test_setposixacl_getntacl_smbd(self): - lp = LoadParm() - s3conf = s3param.get_context() - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) group_SID = s4_passdb.gid_to_sid(os.stat(self.tempf).st_gid) user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) smbd.set_simple_acl(self.tempf, 0640) - facl = getntacl(lp, self.tempf, direct_db_access=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) def test_setposixacl_dir_getntacl_smbd(self): - lp = LoadParm() - s3conf = s3param.get_context() - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) user_SID = s4_passdb.uid_to_sid(os.stat(self.tempdir).st_uid) + BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) + (BA_id,BA_type) = s4_passdb.sid_to_id(BA_sid) + self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) + SO_sid = security.dom_sid(security.SID_BUILTIN_SERVER_OPERATORS) + (SO_id,SO_type) = s4_passdb.sid_to_id(SO_sid) + self.assertEquals(SO_type, idmap.ID_TYPE_BOTH) + smbd.chown(self.tempdir, BA_id, SO_id) smbd.set_simple_acl(self.tempdir, 0750) - facl = getntacl(lp, self.tempdir, direct_db_access=False) - acl = "O:%sG:BAD:(A;;0x001f01ff;;;%s)(A;;0x001200a9;;;BA)(A;;WO;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001f01ff;;;CG)(A;OICIIO;0x001f01ff;;;WD)" % (user_SID, user_SID) + facl = getntacl(self.lp, self.tempdir, direct_db_access=False) + acl = "O:BAG:SOD:(A;;0x001f01ff;;;BA)(A;;0x001200a9;;;SO)(A;;WO;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001f01ff;;;CG)(A;OICIIO;0x001f01ff;;;WD)" anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) def test_setposixacl_group_getntacl_smbd(self): - lp = LoadParm() BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) - s3conf = s3param.get_context() - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) group_SID = s4_passdb.gid_to_sid(os.stat(self.tempf).st_gid) user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) smbd.set_simple_acl(self.tempf, 0640, BA_gid) - facl = getntacl(lp, self.tempf, direct_db_access=False) + facl = getntacl(self.lp, self.tempf, direct_db_access=False) domsid = passdb.get_global_sam_sid() acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) def test_setposixacl_getposixacl(self): - lp = LoadParm() smbd.set_simple_acl(self.tempf, 0640) posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 4) @@ -261,7 +247,6 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[3].a_perm, 7) def test_setposixacl_dir_getposixacl(self): - lp = LoadParm() smbd.set_simple_acl(self.tempdir, 0750) posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) self.assertEquals(posix_acl.count, 4) @@ -279,10 +264,8 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[3].a_perm, 7) def test_setposixacl_group_getposixacl(self): - lp = LoadParm() BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) - s3conf = s3param.get_context() - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) (BA_gid,BA_type) = s4_passdb.sid_to_id(BA_sid) self.assertEquals(BA_type, idmap.ID_TYPE_BOTH) smbd.set_simple_acl(self.tempf, 0670, BA_gid) @@ -307,12 +290,10 @@ class PosixAclMappingTests(TestCaseInTempDir): self.assertEquals(posix_acl.acl[4].a_perm, 7) def test_setntacl_sysvol_check_getposixacl(self): - lp = LoadParm() - s3conf = s3param.get_context() acl = provision.SYSVOL_ACL domsid = passdb.get_global_sam_sid() - setntacl(lp, self.tempf,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp, self.tempf) + setntacl(self.lp, self.tempf,acl,str(domsid), use_ntvfs=False) + facl = getntacl(self.lp, self.tempf) self.assertEquals(facl.as_sddl(domsid),acl) posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) @@ -322,7 +303,7 @@ class PosixAclMappingTests(TestCaseInTempDir): SY_sid = security.dom_sid(security.SID_NT_SYSTEM) AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) # These assertions correct for current plugin_s4_dc selftest # configuration. When other environments have a broad range of @@ -427,12 +408,10 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_sysvol_dir_check_getposixacl(self): - lp = LoadParm() - s3conf = s3param.get_context() acl = provision.SYSVOL_ACL domsid = passdb.get_global_sam_sid() - setntacl(lp, self.tempdir,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp, self.tempdir) + setntacl(self.lp, self.tempdir,acl,str(domsid), use_ntvfs=False) + facl = getntacl(self.lp, self.tempdir) self.assertEquals(facl.as_sddl(domsid),acl) posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) @@ -442,7 +421,7 @@ class PosixAclMappingTests(TestCaseInTempDir): SY_sid = security.dom_sid(security.SID_NT_SYSTEM) AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) # These assertions correct for current plugin_s4_dc selftest # configuration. When other environments have a broad range of @@ -506,12 +485,10 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_policies_dir_check_getposixacl(self): - lp = LoadParm() - s3conf = s3param.get_context() acl = provision.POLICIES_ACL domsid = passdb.get_global_sam_sid() - setntacl(lp, self.tempdir,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp, self.tempdir) + setntacl(self.lp, self.tempdir,acl,str(domsid), use_ntvfs=False) + facl = getntacl(self.lp, self.tempdir) self.assertEquals(facl.as_sddl(domsid),acl) posix_acl = smbd.get_sys_acl(self.tempdir, smb_acl.SMB_ACL_TYPE_ACCESS) @@ -522,7 +499,7 @@ class PosixAclMappingTests(TestCaseInTempDir): AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) PA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_POLICY_ADMINS)) - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) # These assertions correct for current plugin_s4_dc selftest # configuration. When other environments have a broad range of @@ -594,13 +571,11 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_policies_check_getposixacl(self): - lp = LoadParm() - s3conf = s3param.get_context() acl = provision.POLICIES_ACL domsid = passdb.get_global_sam_sid() - setntacl(lp, self.tempf,acl,str(domsid), use_ntvfs=False) - facl = getntacl(lp, self.tempf) + setntacl(self.lp, self.tempf, acl, str(domsid), use_ntvfs=False) + facl = getntacl(self.lp, self.tempf) self.assertEquals(facl.as_sddl(domsid),acl) posix_acl = smbd.get_sys_acl(self.tempf, smb_acl.SMB_ACL_TYPE_ACCESS) @@ -611,7 +586,7 @@ class PosixAclMappingTests(TestCaseInTempDir): AU_sid = security.dom_sid(security.SID_NT_AUTHENTICATED_USERS) PA_sid = security.dom_sid(str(domsid)+"-"+str(security.DOMAIN_RID_POLICY_ADMINS)) - s4_passdb = passdb.PDB(s3conf.get("passdb backend")) + s4_passdb = passdb.PDB(self.lp.get("passdb backend")) # These assertions correct for current plugin_s4_dc selftest # configuration. When other environments have a broad range of @@ -729,9 +704,12 @@ class PosixAclMappingTests(TestCaseInTempDir): super(PosixAclMappingTests, self).setUp() s3conf = s3param.get_context() s3conf.load(self.get_loadparm().configfile) + s3conf.set("xattr_tdb:file", os.path.join(self.tempdir,"xattr.tdb")) + self.lp = s3conf self.tempf = os.path.join(self.tempdir, "test") open(self.tempf, 'w').write("empty") def tearDown(self): smbd.unlink(self.tempf) + os.unlink(os.path.join(self.tempdir,"xattr.tdb")) super(PosixAclMappingTests, self).tearDown() -- 1.7.11.7 From 9a49ca5a889cdfc5baddabaaec4cfc88eb45a1ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Nov 2012 21:48:46 +1100 Subject: [PATCH 33/42] selftest: Avoid returning errors (rather than failures) in gpo test This should help find the real cause of the flakey test, if it ever returns. Andrew Bartlett Reviewed-by: Jelmer Vernooij --- source4/scripting/python/samba/tests/samba_tool/gpo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/tests/samba_tool/gpo.py b/source4/scripting/python/samba/tests/samba_tool/gpo.py index 84154f5..c2e069d 100644 --- a/source4/scripting/python/samba/tests/samba_tool/gpo.py +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -46,9 +46,11 @@ os.environ["SERVER"]) """set up a temporary GPO to work with""" super(GpoCmdTestCase, self).setUp() (result, out, err) = self.runsubcmd("gpo", "create", self.gpo_name, "-H", "ldap://%s" % os.environ["SERVER"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) - self.gpo_guid = "{%s}" % out.split("{")[1].split("}")[0] - self.assertCmdSuccess(result, "Ensuring gpo created successfully") + try: + self.gpo_guid = "{%s}" % out.split("{")[1].split("}")[0] + except IndexError: + self.fail("Failed to find GUID in output: %s" % out) def tearDown(self): """remove the temporary GPO to work with""" -- 1.7.11.7 From 09e4b863095edcaf3ed739ba0e34d537a9b9783e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2012 13:31:53 +1100 Subject: [PATCH 34/42] selftest: Add --tmpdir to 'samba-tool gpo create' test This was the cause of the flakey test, and was only noticed when multiple different users ran autobuild at the same time on the same server. We use shutil.rmtree to wipe the directory before the tests finishes as required by the TestCaseInTempDir class. Andrew Bartlett Reviewed-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Nov 13 10:50:56 CET 2012 on sn-devel-104 --- source4/scripting/python/samba/tests/samba_tool/base.py | 2 +- source4/scripting/python/samba/tests/samba_tool/gpo.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source4/scripting/python/samba/tests/samba_tool/base.py b/source4/scripting/python/samba/tests/samba_tool/base.py index 489d6b5..96f0ddc 100644 --- a/source4/scripting/python/samba/tests/samba_tool/base.py +++ b/source4/scripting/python/samba/tests/samba_tool/base.py @@ -29,7 +29,7 @@ from cStringIO import StringIO from samba.netcmd.main import cmd_sambatool import samba.tests -class SambaToolCmdTest(samba.tests.TestCase): +class SambaToolCmdTest(samba.tests.TestCaseInTempDir): def getSamDB(self, *argv): """a convenience function to get a samdb instance so that we can query it""" diff --git a/source4/scripting/python/samba/tests/samba_tool/gpo.py b/source4/scripting/python/samba/tests/samba_tool/gpo.py index c2e069d..7ada91f 100644 --- a/source4/scripting/python/samba/tests/samba_tool/gpo.py +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -20,6 +20,7 @@ import os from samba.tests.samba_tool.base import SambaToolCmdTest +import shutil class GpoCmdTestCase(SambaToolCmdTest): """Tests for samba-tool time subcommands""" @@ -39,13 +40,18 @@ os.environ["SERVER"]) def test_fetch(self): """Run against a real GPO, and make sure it passes""" - (result, out, err) = self.runsubcmd("gpo", "fetch", self.gpo_guid, "-H", "ldap://%s" % os.environ["SERVER"], "--tmpdir", os.environ['SELFTEST_PREFIX']) + (result, out, err) = self.runsubcmd("gpo", "fetch", self.gpo_guid, "-H", "ldap://%s" % os.environ["SERVER"], "--tmpdir", self.tempdir) self.assertCmdSuccess(result, "Ensuring gpo fetched successfully") + shutil.rmtree(os.path.join(self.tempdir, "policy")) def setUp(self): """set up a temporary GPO to work with""" super(GpoCmdTestCase, self).setUp() - (result, out, err) = self.runsubcmd("gpo", "create", self.gpo_name, "-H", "ldap://%s" % os.environ["SERVER"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) + (result, out, err) = self.runsubcmd("gpo", "create", self.gpo_name, + "-H", "ldap://%s" % os.environ["SERVER"], + "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"]), + "--tmpdir", self.tempdir) + shutil.rmtree(os.path.join(self.tempdir, "policy")) self.assertCmdSuccess(result, "Ensuring gpo created successfully") try: self.gpo_guid = "{%s}" % out.split("{")[1].split("}")[0] -- 1.7.11.7 From d61e13ac5e89eee3188bb50bf70b82fd9bb452d0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2012 12:21:45 -0800 Subject: [PATCH 35/42] Ensure we Correctly set fsp->is_directory before dealing with ACLs. Reviewed by: Jeremy Allison --- source3/torture/cmd_vfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/torture/cmd_vfs.c b/source3/torture/cmd_vfs.c index a37c9fc..64b1b50 100644 --- a/source3/torture/cmd_vfs.c +++ b/source3/torture/cmd_vfs.c @@ -1524,7 +1524,7 @@ static NTSTATUS cmd_set_nt_acl(struct vfs_state *vfs, TALLOC_CTX *mem_ctx, int a fsp->print_file = NULL; fsp->modified = False; fsp->sent_oplock_break = NO_BREAK_SENT; - fsp->is_directory = False; + fsp->is_directory = S_ISDIR(smb_fname->st.st_ex_mode); sd = sddl_decode(talloc_tos(), argv[2], get_global_sam_sid()); -- 1.7.11.7 From b117cce0eb356890f416c984a3f3451673a56977 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2012 12:34:35 -0800 Subject: [PATCH 36/42] smbd: Correctly set fsp->is_directory before dealing with ACLs Change set_nt_acl_no_snum() to correctly set up the fsp. This does a stat on a real fsp in set_nt_acl_no_snum. Reviewed by: Jeremy Allison --- source3/smbd/pysmbd.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/source3/smbd/pysmbd.c b/source3/smbd/pysmbd.c index 1489355..78c2bcb 100644 --- a/source3/smbd/pysmbd.c +++ b/source3/smbd/pysmbd.c @@ -88,7 +88,7 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, NTSTATUS status = NT_STATUS_OK; files_struct *fsp; struct smb_filename *smb_fname = NULL; - int flags; + int flags, ret; mode_t saved_umask; if (!posix_locking_init(false)) { @@ -159,6 +159,29 @@ static NTSTATUS set_nt_acl_no_snum(const char *fname, return NT_STATUS_UNSUCCESSFUL; } + ret = SMB_VFS_FSTAT(fsp, &smb_fname->st); + if (ret == -1) { + /* If we have an fd, this stat should succeed. */ + DEBUG(0,("Error doing fstat on open file %s " + "(%s)\n", + smb_fname_str_dbg(smb_fname), + strerror(errno) )); + TALLOC_FREE(frame); + umask(saved_umask); + return map_nt_error_from_unix(errno); + } + + fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st); + fsp->vuid = UID_FIELD_INVALID; + fsp->file_pid = 0; + fsp->can_lock = True; + fsp->can_read = True; + fsp->can_write = True; + fsp->print_file = NULL; + fsp->modified = False; + fsp->sent_oplock_break = NO_BREAK_SENT; + fsp->is_directory = S_ISDIR(smb_fname->st.st_ex_mode); + status = SMB_VFS_FSET_NT_ACL( fsp, security_info_sent, sd); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("set_nt_acl_no_snum: fset_nt_acl returned %s.\n", nt_errstr(status))); -- 1.7.11.7 From b673855131b9181701c60b75da92aa191947b5ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Nov 2012 17:11:34 +1100 Subject: [PATCH 37/42] smbd: Remove NT4 compatability handling in posix -> NT ACL conversion NT4 is long dead, and we should not change which ACL we return based on what we think the client is. The reason we should not do this, is that if we are using vfs_acl_xattr then the hash will break if we do. Additionally, it would require that the python VFS interface set the global remote_arch to fake up being a modern client. This instead seems cleaner and removes untested code (the tests are updated to then handle the results of the modern codepath). The supporting 'acl compatability' parameter is also removed. Andrew Bartlett Reviewed by: Jeremy Allison --- docs-xml/smbdotconf/vfs/aclcompatibility.xml | 17 ---- lib/param/param_functions.c | 1 - lib/param/param_table.c | 19 ---- source3/include/proto.h | 1 - source3/smbd/posix_acls.c | 108 +---------------------- source3/smbd/proto.h | 1 - source4/libcli/pysmb.c | 7 +- source4/scripting/python/samba/tests/posixacl.py | 12 +-- 8 files changed, 11 insertions(+), 155 deletions(-) delete mode 100644 docs-xml/smbdotconf/vfs/aclcompatibility.xml diff --git a/docs-xml/smbdotconf/vfs/aclcompatibility.xml b/docs-xml/smbdotconf/vfs/aclcompatibility.xml deleted file mode 100644 index 95f42cf..0000000 --- a/docs-xml/smbdotconf/vfs/aclcompatibility.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - This parameter specifies what OS ACL semantics should - be compatible with. Possible values are winnt for Windows NT 4, - win2k for Windows 2000 and above and auto. - If you specify auto, the value for this parameter - will be based upon the version of the client. There should - be no reason to change this parameter from the default. - - -Auto -win2k - diff --git a/lib/param/param_functions.c b/lib/param/param_functions.c index d5cd018..94652fa 100644 --- a/lib/param/param_functions.c +++ b/lib/param/param_functions.c @@ -266,7 +266,6 @@ FN_GLOBAL_CONST_STRING(winbindd_socket_directory, szWinbinddSocketDirectory) FN_GLOBAL_CONST_STRING(winbind_separator, szWinbindSeparator) FN_GLOBAL_CONST_STRING(workgroup, szWorkgroup) FN_GLOBAL_CONST_STRING(wtmpdir, szWtmpDir) -FN_GLOBAL_INTEGER(acl_compatibility, iAclCompat) FN_GLOBAL_INTEGER(afs_token_lifetime, iAfsTokenLifetime) FN_GLOBAL_INTEGER(algorithmic_rid_base, AlgorithmicRidBase) FN_GLOBAL_INTEGER(allow_dns_updates, allow_dns_updates) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 01f65fe..a73cd96 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -180,16 +180,6 @@ static const struct enum_list enum_kerberos_method[] = { {-1, NULL} }; - -/* ACL compatibility options. */ -static const struct enum_list enum_acl_compat_vals[] = { - { ACL_COMPAT_AUTO, "auto" }, - { ACL_COMPAT_WINNT, "winnt" }, - { ACL_COMPAT_WIN2K, "win2k" }, - { -1, NULL} -}; - - static const struct enum_list enum_printing[] = { {PRINT_SYSV, "sysv"}, {PRINT_AIX, "aix"}, @@ -1459,15 +1449,6 @@ static struct parm_struct parm_table[] = { .flags = FLAG_ADVANCED, }, { - .label = "acl compatibility", - .type = P_ENUM, - .p_class = P_GLOBAL, - .offset = GLOBAL_VAR(iAclCompat), - .special = NULL, - .enum_list = enum_acl_compat_vals, - .flags = FLAG_ADVANCED | FLAG_SHARE | FLAG_GLOBAL, - }, - { .label = "defer sharing violations", .type = P_BOOL, .p_class = P_GLOBAL, diff --git a/source3/include/proto.h b/source3/include/proto.h index 7c5a5a7..5f3d937 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1068,7 +1068,6 @@ char *lp_wins_hook(TALLOC_CTX *ctx); const char *lp_template_homedir(void); const char *lp_template_shell(void); const char *lp_winbind_separator(void); -int lp_acl_compatibility(void); bool lp_winbind_enum_users(void); bool lp_winbind_enum_groups(void); bool lp_winbind_use_default_domain(void); diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 7f12f4b..4e93fef 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1058,24 +1058,6 @@ static void merge_aces( canon_ace **pp_list_head, bool dir_acl) } /**************************************************************************** - Check if we need to return NT4.x compatible ACL entries. -****************************************************************************/ - -bool nt4_compatible_acls(void) -{ - int compat = lp_acl_compatibility(); - - if (compat == ACL_COMPAT_AUTO) { - enum remote_arch_types ra_type = get_remote_arch(); - - /* Automatically adapt to client */ - return (ra_type <= RA_WINNT); - } else - return (compat == ACL_COMPAT_WINNT); -} - - -/**************************************************************************** Map canon_ace perms to permission bits NT. The attr element is not used here - we only process deny entries on set, not get. Deny entries are implicit on get with ace->perms = 0. @@ -1106,10 +1088,7 @@ uint32_t map_canon_ace_perms(int snum, * to be changed in the future. */ - if (nt4_compatible_acls()) - nt_mask = UNIX_ACCESS_NONE; - else - nt_mask = 0; + nt_mask = 0; } else { if (directory_ace) { nt_mask |= ((perms & S_IRUSR) ? UNIX_DIRECTORY_ACCESS_R : 0 ); @@ -1972,26 +1951,6 @@ static bool create_canon_ace_lists(files_struct *fsp, DEBUG(3,("create_canon_ace_lists: unable to set anything but an ALLOW or DENY ACE.\n")); return False; } - - if (nt4_compatible_acls()) { - /* - * The security mask may be UNIX_ACCESS_NONE which should map into - * no permissions (we overload the WRITE_OWNER bit for this) or it - * should be one of the ALL/EXECUTE/READ/WRITE bits. Arrange for this - * to be so. Any other bits override the UNIX_ACCESS_NONE bit. - */ - - /* - * Convert GENERIC bits to specific bits. - */ - - se_map_generic(&psa->access_mask, &file_generic_mapping); - - psa->access_mask &= (UNIX_ACCESS_NONE|FILE_ALL_ACCESS); - - if(psa->access_mask != UNIX_ACCESS_NONE) - psa->access_mask &= ~UNIX_ACCESS_NONE; - } } /* @@ -3182,22 +3141,6 @@ static bool set_canon_ace_list(files_struct *fsp, } /**************************************************************************** - Find a particular canon_ace entry. -****************************************************************************/ - -static struct canon_ace *canon_ace_entry_for(struct canon_ace *list, SMB_ACL_TAG_T type, struct unixid *id) -{ - while (list) { - if (list->type == type && ((type != SMB_ACL_USER && type != SMB_ACL_GROUP) || - (type == SMB_ACL_USER && id && id->id == list->unix_ug.id) || - (type == SMB_ACL_GROUP && id && id->id == list->unix_ug.id))) - break; - list = list->next; - } - return list; -} - -/**************************************************************************** ****************************************************************************/ @@ -3479,55 +3422,6 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, canon_ace *ace; enum security_ace_type nt_acl_type; - if (nt4_compatible_acls() && dir_ace) { - /* - * NT 4 chokes if an ACL contains an INHERIT_ONLY entry - * but no non-INHERIT_ONLY entry for one SID. So we only - * remove entries from the Access ACL if the - * corresponding Default ACL entries have also been - * removed. ACEs for CREATOR-OWNER and CREATOR-GROUP - * are exceptions. We can do nothing - * intelligent if the Default ACL contains entries that - * are not also contained in the Access ACL, so this - * case will still fail under NT 4. - */ - - ace = canon_ace_entry_for(dir_ace, SMB_ACL_OTHER, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - TALLOC_FREE(ace); - - ace = canon_ace_entry_for(file_ace, SMB_ACL_OTHER, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(file_ace, ace); - TALLOC_FREE(ace); - } - } - - /* - * WinNT doesn't usually have Creator Group - * in browse lists, so we send this entry to - * WinNT even if it contains no relevant - * permissions. Once we can add - * Creator Group to browse lists we can - * re-enable this. - */ - -#if 0 - ace = canon_ace_entry_for(dir_ace, SMB_ACL_GROUP_OBJ, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(dir_ace, ace); - TALLOC_FREE(ace); - } -#endif - - ace = canon_ace_entry_for(file_ace, SMB_ACL_GROUP_OBJ, NULL); - if (ace && !ace->perms) { - DLIST_REMOVE(file_ace, ace); - TALLOC_FREE(ace); - } - } - num_acls = count_canon_ace_list(file_ace); num_def_acls = count_canon_ace_list(dir_ace); diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h index 2e53a87..b48cf44 100644 --- a/source3/smbd/proto.h +++ b/source3/smbd/proto.h @@ -702,7 +702,6 @@ void reply_pipe_read_and_X(struct smb_request *req); /* The following definitions come from smbd/posix_acls.c */ void create_file_sids(const SMB_STRUCT_STAT *psbuf, struct dom_sid *powner_sid, struct dom_sid *pgroup_sid); -bool nt4_compatible_acls(void); uint32_t map_canon_ace_perms(int snum, enum security_ace_type *pacl_type, mode_t perms, diff --git a/source4/libcli/pysmb.c b/source4/libcli/pysmb.c index 1122305..fb981c7 100644 --- a/source4/libcli/pysmb.c +++ b/source4/libcli/pysmb.c @@ -317,10 +317,11 @@ static PyObject *py_smb_getacl(pytalloc_Object *self, PyObject *args, PyObject * union smb_fileinfo fio; struct smb_private_data *spdata; const char *filename; - int sinfo = 0; + uint32_t sinfo = 0; + int access_mask = SEC_FLAG_MAXIMUM_ALLOWED; int fnum; - if (!PyArg_ParseTuple(args, "s|i:get_acl", &filename, &sinfo)) { + if (!PyArg_ParseTuple(args, "s|Ii:get_acl", &filename, &sinfo, &access_mask)) { return NULL; } @@ -331,7 +332,7 @@ static PyObject *py_smb_getacl(pytalloc_Object *self, PyObject *args, PyObject * io.generic.level = RAW_OPEN_NTCREATEX; io.ntcreatex.in.root_fid.fnum = 0; io.ntcreatex.in.flags = 0; - io.ntcreatex.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + io.ntcreatex.in.access_mask = access_mask; io.ntcreatex.in.create_options = 0; io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | diff --git a/source4/scripting/python/samba/tests/posixacl.py b/source4/scripting/python/samba/tests/posixacl.py index f949ab4..652721f 100644 --- a/source4/scripting/python/samba/tests/posixacl.py +++ b/source4/scripting/python/samba/tests/posixacl.py @@ -92,7 +92,7 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_smbd_invalidate_getntacl_smbd(self): acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x001200a9;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x001200a9;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;;;;WD)" os.chmod(self.tempf, 0750) setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) @@ -122,7 +122,7 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_smbd_setposixacl_getntacl_smbd(self): acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" - simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;;;;WD)" setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code smbd.set_simple_acl(self.tempf, 0640) @@ -133,7 +133,7 @@ class PosixAclMappingTests(TestCaseInTempDir): def test_setntacl_smbd_setposixacl_group_getntacl_smbd(self): acl = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;OICI;0x001f01ff;;;S-1-5-21-2212615479-2695158682-2101375467-512)" BA_sid = security.dom_sid(security.SID_BUILTIN_ADMINISTRATORS) - simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;BA)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;WO;;;WD)" + simple_acl_from_posix = "O:S-1-5-21-2212615479-2695158682-2101375467-512G:S-1-5-21-2212615479-2695158682-2101375467-513D:(A;;0x001f019f;;;S-1-5-21-2212615479-2695158682-2101375467-512)(A;;0x00120089;;;BA)(A;;0x00120089;;;S-1-5-21-2212615479-2695158682-2101375467-513)(A;;;;;WD)" setntacl(self.lp, self.tempf, acl, "S-1-5-21-2212615479-2695158682-2101375467", use_ntvfs=False) # This invalidates the hash of the NT acl just set because there is a hook in the posix ACL set code s4_passdb = passdb.PDB(self.lp.get("passdb backend")) @@ -193,7 +193,7 @@ class PosixAclMappingTests(TestCaseInTempDir): user_SID = s4_passdb.uid_to_sid(os.stat(self.tempf).st_uid) smbd.set_simple_acl(self.tempf, 0640) facl = getntacl(self.lp, self.tempf, direct_db_access=False) - acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) + acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;%s)(A;;;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) @@ -210,7 +210,7 @@ class PosixAclMappingTests(TestCaseInTempDir): smbd.chown(self.tempdir, BA_id, SO_id) smbd.set_simple_acl(self.tempdir, 0750) facl = getntacl(self.lp, self.tempdir, direct_db_access=False) - acl = "O:BAG:SOD:(A;;0x001f01ff;;;BA)(A;;0x001200a9;;;SO)(A;;WO;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001f01ff;;;CG)(A;OICIIO;0x001f01ff;;;WD)" + acl = "O:BAG:SOD:(A;;0x001f01ff;;;BA)(A;;0x001200a9;;;SO)(A;;;;;WD)(A;OICIIO;0x001f01ff;;;CO)(A;OICIIO;0x001f01ff;;;CG)(A;OICIIO;0x001f01ff;;;WD)" anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) @@ -225,7 +225,7 @@ class PosixAclMappingTests(TestCaseInTempDir): smbd.set_simple_acl(self.tempf, 0640, BA_gid) facl = getntacl(self.lp, self.tempf, direct_db_access=False) domsid = passdb.get_global_sam_sid() - acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;WO;;;WD)" % (user_SID, group_SID, user_SID, group_SID) + acl = "O:%sG:%sD:(A;;0x001f019f;;;%s)(A;;0x00120089;;;BA)(A;;0x00120089;;;%s)(A;;;;;WD)" % (user_SID, group_SID, user_SID, group_SID) anysid = security.dom_sid(security.SID_NT_SELF) self.assertEquals(acl, facl.as_sddl(anysid)) -- 1.7.11.7 From 7ff8a467730a5913c57680683c6887aef3feb010 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2012 16:45:03 +1100 Subject: [PATCH 38/42] ntvfs: Fill in sd->type based on the new ACL being added Previously we would not change the type field, and just relied on what was in the original ACL based on the default SD. This is required to ensure the SEC_DESC_DACL_PROTECTED is set which is in turn required for GPOs to be set correctly to match what windows does. Andrew Bartlett Reviewed by: Jeremy Allison --- source4/ntvfs/posix/pvfs_acl.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source4/ntvfs/posix/pvfs_acl.c b/source4/ntvfs/posix/pvfs_acl.c index 1519631..4e9c1ac 100644 --- a/source4/ntvfs/posix/pvfs_acl.c +++ b/source4/ntvfs/posix/pvfs_acl.c @@ -330,6 +330,7 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } sd->owner_sid = new_sd->owner_sid; } + if (secinfo_flags & SECINFO_GROUP) { if (!(access_mask & SEC_STD_WRITE_OWNER)) { return NT_STATUS_ACCESS_DENIED; @@ -349,19 +350,39 @@ NTSTATUS pvfs_acl_set(struct pvfs_state *pvfs, } sd->group_sid = new_sd->group_sid; } + if (secinfo_flags & SECINFO_DACL) { if (!(access_mask & SEC_STD_WRITE_DAC)) { return NT_STATUS_ACCESS_DENIED; } sd->dacl = new_sd->dacl; pvfs_translate_generic_bits(sd->dacl); + sd->type |= SEC_DESC_DACL_PRESENT; } + if (secinfo_flags & SECINFO_SACL) { if (!(access_mask & SEC_FLAG_SYSTEM_SECURITY)) { return NT_STATUS_ACCESS_DENIED; } sd->sacl = new_sd->sacl; pvfs_translate_generic_bits(sd->sacl); + sd->type |= SEC_DESC_SACL_PRESENT; + } + + if (secinfo_flags & SECINFO_PROTECTED_DACL) { + if (new_sd->type & SEC_DESC_DACL_PROTECTED) { + sd->type |= SEC_DESC_DACL_PROTECTED; + } else { + sd->type &= ~SEC_DESC_DACL_PROTECTED; + } + } + + if (secinfo_flags & SECINFO_PROTECTED_SACL) { + if (new_sd->type & SEC_DESC_SACL_PROTECTED) { + sd->type |= SEC_DESC_SACL_PROTECTED; + } else { + sd->type &= ~SEC_DESC_SACL_PROTECTED; + } } if (new_uid == old_uid) { -- 1.7.11.7 From fb423e2907365ea64f5d26960a47722c06cc75f4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 Nov 2012 16:03:27 +1100 Subject: [PATCH 39/42] scripting ntacls: Do not place a SACL in the GPO filesystem ACL On a new GPO created on windows, the SACL is not used. Andrew Bartlett Reviewed by: Jeremy Allison Autobuild-User(master): Andrew Bartlett Autobuild-Date(master): Wed Nov 14 00:34:50 CET 2012 on sn-devel-104 --- source4/scripting/python/samba/ntacls.py | 1 - 1 file changed, 1 deletion(-) diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py index 89d450a..8992b61 100644 --- a/source4/scripting/python/samba/ntacls.py +++ b/source4/scripting/python/samba/ntacls.py @@ -211,7 +211,6 @@ def dsacl2fsacl(dssddl, sid): fdescr.group_sid = ref.group_sid fdescr.type = ref.type fdescr.revision = ref.revision - fdescr.sacl = ref.sacl aces = ref.dacl.aces for i in range(0, len(aces)): ace = aces[i] -- 1.7.11.7 From 6bc511f02fba7b00fe4087f7570f8a064119f333 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Nov 2012 19:36:28 +1100 Subject: [PATCH 40/42] samba-tool: Add new samba-tool gpo aclcheck and test Reviewed-by: Jelmer Vernooij --- source4/scripting/python/samba/netcmd/gpo.py | 63 ++++++++++++++++++++++ .../scripting/python/samba/tests/samba_tool/gpo.py | 10 ++++ 2 files changed, 73 insertions(+) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 347231b..f70317a 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -1072,6 +1072,68 @@ class cmd_del(Command): self.outf.write("GPO %s deleted.\n" % gpo) +class cmd_aclcheck(Command): + """Check all GPOs have matching LDAP and DS ACLs.""" + + synopsis = "%prog [options]" + + takes_optiongroups = { + "sambaopts": options.SambaOptions, + "versionopts": options.VersionOptions, + "credopts": options.CredentialsOptions, + } + + takes_options = [ + Option("-H", "--URL", help="LDB URL for database or target server", type=str, + metavar="URL", dest="H") + ] + + def run(self, H=None, sambaopts=None, credopts=None, versionopts=None): + + self.lp = sambaopts.get_loadparm() + self.creds = credopts.get_credentials(self.lp, fallback_machine=True) + + self.url = dc_url(self.lp, self.creds, H) + + # We need to know writable DC to setup SMB connection + if H and H.startswith('ldap://'): + dc_hostname = H[7:] + self.url = H + else: + dc_hostname = netcmd_finddc(self.lp, self.creds) + self.url = dc_url(self.lp, self.creds, dc=dc_hostname) + + samdb_connect(self) + + msg = get_gpo_info(self.samdb, None) + + for m in msg: + # verify UNC path + unc = m['gPCFileSysPath'][0] + try: + [dom_name, service, sharepath] = parse_unc(unc) + except ValueError: + raise CommandError("Invalid GPO path (%s)" % unc) + + # SMB connect to DC + try: + conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds) + except Exception: + raise CommandError("Error connecting to '%s' using SMB" % dc_hostname) + + fs_sd = conn.get_acl(sharepath, security.SECINFO_OWNER | security.SECINFO_GROUP | security.SECINFO_DACL, security.SEC_FLAG_MAXIMUM_ALLOWED) + + ds_sd_ndr = m['ntSecurityDescriptor'][0] + ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl() + + # Create a file system security descriptor + domain_sid = security.dom_sid(self.samdb.get_domain_sid()) + expected_fs_sddl = dsacl2fsacl(ds_sd, domain_sid) + + if (fs_sd.as_sddl(domain_sid) != expected_fs_sddl): + raise CommandError("Invalid GPO ACL %s on path (%s), should be %s" % (fs_sd.as_sddl(domain_sid), sharepath, expected_fs_sddl)) + + class cmd_gpo(SuperCommand): """Group Policy Object (GPO) management.""" @@ -1088,3 +1150,4 @@ class cmd_gpo(SuperCommand): subcommands["fetch"] = cmd_fetch() subcommands["create"] = cmd_create() subcommands["del"] = cmd_del() + subcommands["aclcheck"] = cmd_aclcheck() diff --git a/source4/scripting/python/samba/tests/samba_tool/gpo.py b/source4/scripting/python/samba/tests/samba_tool/gpo.py index 7ada91f..82e7268 100644 --- a/source4/scripting/python/samba/tests/samba_tool/gpo.py +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -44,6 +44,16 @@ os.environ["SERVER"]) self.assertCmdSuccess(result, "Ensuring gpo fetched successfully") shutil.rmtree(os.path.join(self.tempdir, "policy")) + def test_show(self): + """Show a real GPO, and make sure it passes""" + (result, out, err) = self.runsubcmd("gpo", "show", self.gpo_guid, "-H", "ldap://%s" % os.environ["SERVER"]) + self.assertCmdSuccess(result, "Ensuring gpo fetched successfully") + + def test_aclcheck(self): + """Check all the GPOs on the remote server have correct ACLs""" + (result, out, err) = self.runsubcmd("gpo", "aclcheck", "-H", "ldap://%s" % os.environ["SERVER"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) + self.assertCmdSuccess(result, "Ensuring gpo checked successfully") + def setUp(self): """set up a temporary GPO to work with""" super(GpoCmdTestCase, self).setUp() -- 1.7.11.7 From 33ac0cc41dab9cc995f23f78d66a8a766e283193 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 16 Nov 2012 10:30:44 +1100 Subject: [PATCH 41/42] s3-param: Handle setting default AD DC per-share settings in init_locals() This function is helpfully called between when we finish processing the globals and when we start processing the individual shares. This means that the "vfs objects" and other per-share settings we specify here become the defaults for (eg) [netlogon] and [sysvol] but the admin can override these on a per-share basis or (as we must in make test) for the whole server. This broke setting and fetching of group policy objects from Windows clients, since this setting was moved from fileserver.conf in 8518dd6406c0132dfd8c44e084c2b39792974f2c, and wasn't found in 'make test' because we have to override the vfs objects to insert the xattr_tdb and fake_acl modules. Andrew Bartlett Reviewed-by: Michael Adam --- source3/param/loadparm.c | 56 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 12cb8db..5229a54 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -3469,12 +3469,41 @@ static bool equal_parameter(parm_type type, void *ptr1, void *ptr2) } /*************************************************************************** - Initialize any local varients in the sDefault table. + Initialize any local variables in the sDefault table, after parsing a + [globals] section. ***************************************************************************/ void init_locals(void) { - /* None as yet. */ + /* + * We run this check once the [globals] is parsed, to force + * the VFS objects and other per-share settings we need for + * the standard way a AD DC is operated. We may change these + * as our code evolves, which is why we force these settings. + * + * We can't do this at the end of lp_load_ex(), as by that + * point the services have been loaded and they will already + * have "" as their vfs objects. + */ + if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { + const char **vfs_objects = lp_vfs_objects(-1); + if (!vfs_objects || !vfs_objects[0]) { + if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) { + lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb"); + } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) { + lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb"); + } else { + lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr"); + } + } + + lp_do_parameter(-1, "map hidden", "no"); + lp_do_parameter(-1, "map system", "no"); + lp_do_parameter(-1, "map readonly", "no"); + lp_do_parameter(-1, "store dos attributes", "yes"); + lp_do_parameter(-1, "create mask", "0777"); + lp_do_parameter(-1, "directory mask", "0777"); + } } /*************************************************************************** @@ -4887,17 +4916,13 @@ static bool lp_load_ex(const char *pszFname, fault_configure(smb_panic_s3); + /* + * We run this check once the whole smb.conf is parsed, to + * force some settings for the standard way a AD DC is + * operated. We may changed these as our code evolves, which + * is why we force these settings. + */ if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) { - const char **vfs_objects = lp_vfs_objects(-1); - if (!vfs_objects || !vfs_objects[0]) { - if (lp_parm_const_string(-1, "xattr_tdb", "file", NULL)) { - lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr xattr_tdb"); - } else if (lp_parm_const_string(-1, "posix", "eadb", NULL)) { - lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr posix_eadb"); - } else { - lp_do_parameter(-1, "vfs objects", "dfs_samba4 acl_xattr"); - } - } lp_do_parameter(-1, "passdb backend", "samba_dsdb"); lp_do_parameter(-1, "rpc_server:default", "external"); @@ -4909,13 +4934,6 @@ static bool lp_load_ex(const char *pszFname, lp_do_parameter(-1, "rpc_server:spoolss", "embedded"); lp_do_parameter(-1, "rpc_daemon:spoolssd", "embedded"); lp_do_parameter(-1, "rpc_server:tcpip", "no"); - - lp_do_parameter(-1, "map hidden", "no"); - lp_do_parameter(-1, "map system", "no"); - lp_do_parameter(-1, "map readonly", "no"); - lp_do_parameter(-1, "store dos attributes", "yes"); - lp_do_parameter(-1, "create mask", "0777"); - lp_do_parameter(-1, "directory mask", "0777"); } bAllowIncludeRegistry = true; -- 1.7.11.7 From 80b9f48c05e6a643da7694627dbd7d2055f2d0db Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 16 Nov 2012 01:00:21 +0100 Subject: [PATCH 42/42] s3:param: make init_locals() static. it is only used in loadparm.c Signed-off-by: Michael Adam Reviewed-by: Andrew Bartlett Autobuild-User(master): Michael Adam Autobuild-Date(master): Fri Nov 16 03:33:34 CET 2012 on sn-devel-104 --- source3/include/proto.h | 1 - source3/param/loadparm.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index 5f3d937..bcecde9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1408,7 +1408,6 @@ void *lp_local_ptr_by_snum(int snum, struct parm_struct *parm); bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue); bool lp_set_cmdline(const char *pszParmName, const char *pszParmValue); bool lp_set_option(const char *option); -void init_locals(void); bool lp_is_default(int snum, struct parm_struct *parm); bool dump_a_parameter(int snum, char *parm_name, FILE * f, bool isGlobal); struct parm_struct *lp_get_parameter(const char *param_name); diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5229a54..8ad0fc9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -3473,7 +3473,7 @@ static bool equal_parameter(parm_type type, void *ptr1, void *ptr2) [globals] section. ***************************************************************************/ -void init_locals(void) +static void init_locals(void) { /* * We run this check once the [globals] is parsed, to force -- 1.7.11.7