From 8f0bb1928f282ef0eaee5e8788e79c9709941e4c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Nov 2012 14:51:46 +0100 Subject: [PATCH 01/19] s4:netcmd/gpo.py: s/ntSecurityDescriptor/nTSecurityDescriptor Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit f843c04b0f2314ccedb4759c85721773845eb207) --- source4/scripting/python/samba/netcmd/gpo.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index f70317a..656b2bd 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -389,13 +389,13 @@ class cmd_list(Command): try: gmsg = self.samdb.search(base=g['dn'], scope=ldb.SCOPE_BASE, attrs=['name', 'displayName', 'flags', - 'ntSecurityDescriptor']) + 'nTSecurityDescriptor']) except Exception: self.outf.write("Failed to fetch gpo object %s\n" % g['dn']) continue - secdesc_ndr = gmsg[0]['ntSecurityDescriptor'][0] + secdesc_ndr = gmsg[0]['nTSecurityDescriptor'][0] secdesc = ndr_unpack(security.descriptor, secdesc_ndr) try: @@ -465,7 +465,7 @@ class cmd_show(Command): except Exception: raise CommandError("GPO '%s' does not exist" % gpo) - secdesc_ndr = msg['ntSecurityDescriptor'][0] + secdesc_ndr = msg['nTSecurityDescriptor'][0] secdesc = ndr_unpack(security.descriptor, secdesc_ndr) self.outf.write("GPO : %s\n" % msg['name'][0]) @@ -971,7 +971,7 @@ class cmd_create(Command): # Get new security descriptor msg = get_gpo_info(self.samdb, gpo=gpo)[0] - ds_sd_ndr = msg['ntSecurityDescriptor'][0] + ds_sd_ndr = msg['nTSecurityDescriptor'][0] ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl() # Create a file system security descriptor @@ -1123,7 +1123,7 @@ class cmd_aclcheck(Command): 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 = m['nTSecurityDescriptor'][0] ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl() # Create a file system security descriptor -- 1.7.9.5 From d09573d0e5aa87b10edaf9a752f84f339f13b9c2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 17 Nov 2012 07:13:40 +0100 Subject: [PATCH 02/19] s4:netcmd/gpo.py: the nTSecurityDescriptor may not be visible for the current user Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 6bffad67d24df2c90b174bbcc9c578899783a834) --- source4/scripting/python/samba/netcmd/gpo.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 656b2bd..1c6f25d 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -465,8 +465,12 @@ class cmd_show(Command): except Exception: raise CommandError("GPO '%s' does not exist" % gpo) - secdesc_ndr = msg['nTSecurityDescriptor'][0] - secdesc = ndr_unpack(security.descriptor, secdesc_ndr) + try: + secdesc_ndr = msg['nTSecurityDescriptor'][0] + secdesc = ndr_unpack(security.descriptor, secdesc_ndr) + secdesc_sddl = secdesc.as_sddl() + except Exception: + secdesc_sddl = "" self.outf.write("GPO : %s\n" % msg['name'][0]) self.outf.write("display name : %s\n" % msg['displayName'][0]) @@ -474,7 +478,7 @@ class cmd_show(Command): self.outf.write("dn : %s\n" % msg.dn) self.outf.write("version : %s\n" % attr_default(msg, 'versionNumber', '0')) self.outf.write("flags : %s\n" % gpo_flags_string(int(attr_default(msg, 'flags', 0)))) - self.outf.write("ACL : %s\n" % secdesc.as_sddl()) + self.outf.write("ACL : %s\n" % secdesc_sddl) self.outf.write("\n") -- 1.7.9.5 From 9cd25c8dc036434cff41f4283cd7151296a3a216 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Nov 2012 14:56:56 +0100 Subject: [PATCH 03/19] s4:netcmd/gpo.py: only ask for OWNER/GROUP/DACL when validating the nTSecurityDescriptor Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 67799962b8e6e16ac18466658a3f9924854e32f7) --- source4/scripting/python/samba/netcmd/gpo.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 1c6f25d..f57c965 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -387,17 +387,18 @@ class cmd_list(Command): continue try: + sd_flags=security.SECINFO_OWNER|security.SECINFO_GROUP|security.SECINFO_DACL gmsg = self.samdb.search(base=g['dn'], scope=ldb.SCOPE_BASE, attrs=['name', 'displayName', 'flags', - 'nTSecurityDescriptor']) + 'nTSecurityDescriptor'], + controls=['sd_flags:1:%d' % sd_flags]) + secdesc_ndr = gmsg[0]['nTSecurityDescriptor'][0] + secdesc = ndr_unpack(security.descriptor, secdesc_ndr) except Exception: - self.outf.write("Failed to fetch gpo object %s\n" % + self.outf.write("Failed to fetch gpo object with nTSecurityDescriptor %s\n" % g['dn']) continue - secdesc_ndr = gmsg[0]['nTSecurityDescriptor'][0] - secdesc = ndr_unpack(security.descriptor, secdesc_ndr) - try: samba.security.access_check(secdesc, token, security.SEC_STD_READ_CONTROL | -- 1.7.9.5 From 2923917ba12494c3de0b1ab1329f209258da4635 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Nov 2012 14:58:13 +0100 Subject: [PATCH 04/19] s4:netcmd/gpo.py: let get_gpo_info explicitly ask for the full ntSecurityDescriptor Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 325e92190852ae317c42c26ab86d32818d119381) --- source4/scripting/python/samba/netcmd/gpo.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index f57c965..cc63819 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -126,7 +126,8 @@ def get_gpo_dn(samdb, gpo): return dn -def get_gpo_info(samdb, gpo=None, displayname=None, dn=None): +def get_gpo_info(samdb, gpo=None, displayname=None, dn=None, + sd_flags=security.SECINFO_OWNER|security.SECINFO_GROUP|security.SECINFO_DACL|security.SECINFO_SACL): '''Get GPO information using gpo, displayname or dn''' policies_dn = samdb.get_default_basedn() @@ -154,7 +155,8 @@ def get_gpo_info(samdb, gpo=None, displayname=None, dn=None): 'flags', 'name', 'displayName', - 'gPCFileSysPath']) + 'gPCFileSysPath'], + controls=['sd_flags:1:%d' % sd_flags]) except Exception, e: if gpo is not None: mesg = "Cannot get information for GPO %s" % gpo -- 1.7.9.5 From 74dc0a0d2147964e56bbf5aef0a86a44a6b01f98 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 20 Nov 2012 15:02:05 +0100 Subject: [PATCH 05/19] s4:tests/samba_tool/gpo.py: add test_show_as_admin() This calls samba-tool gpo show as admin (which should be able to see the full nTSecurityDescriptor. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit a58124208006ba9311588554b147acfb86d4d4eb) --- .../scripting/python/samba/tests/samba_tool/gpo.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source4/scripting/python/samba/tests/samba_tool/gpo.py b/source4/scripting/python/samba/tests/samba_tool/gpo.py index 82e7268..ce8c65f 100644 --- a/source4/scripting/python/samba/tests/samba_tool/gpo.py +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -49,6 +49,11 @@ os.environ["SERVER"]) (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_show_as_admin(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"], "-U%s%%%s" % (os.environ["USERNAME"], os.environ["PASSWORD"])) + 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"])) -- 1.7.9.5 From ea71562026f8306bbbe740570c1ad27fbd7762ae Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 27 Nov 2012 16:43:25 +0100 Subject: [PATCH 06/19] s4:tests/samba_tool/gpo.py: fix accidential line break Signed-off-by: Michael Adam Reviewed-by: Stefan Metzmacher (cherry picked from commit 4970d3cacbd6b9a76e64030cc79628f3dfecce1b) --- .../scripting/python/samba/tests/samba_tool/gpo.py | 3 +-- 1 file changed, 1 insertion(+), 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 ce8c65f..e20a977 100644 --- a/source4/scripting/python/samba/tests/samba_tool/gpo.py +++ b/source4/scripting/python/samba/tests/samba_tool/gpo.py @@ -34,8 +34,7 @@ class GpoCmdTestCase(SambaToolCmdTest): 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"]) + (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): -- 1.7.9.5 From 67c0d4fbab3ae1e8b3ac4d1cb659f937af58e61d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 10:00:03 +0100 Subject: [PATCH 07/19] s3:smbd/open: use Builtin_Administrators as owner of files (if possible) We do this if the idmap layer resolves Builtin_Administrators as ID_TYPE_BOTH and if the current token has the Builtin_Administrators SID or it's SYSTEM. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 0a3396b53683f5efe439bfb8395e275f53108255) --- source3/smbd/open.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 794ca3b..1139386 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -28,6 +28,8 @@ #include "../libcli/security/security.h" #include "../librpc/gen_ndr/ndr_security.h" #include "../librpc/gen_ndr/open_files.h" +#include "../librpc/gen_ndr/idmap.h" +#include "passdb/lookup_sid.h" #include "auth.h" #include "serverid.h" #include "messages.h" @@ -3432,11 +3434,14 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) struct security_descriptor *parent_desc = NULL; NTSTATUS status = NT_STATUS_OK; struct security_descriptor *psd = NULL; - struct dom_sid *owner_sid = NULL; - struct dom_sid *group_sid = NULL; + const struct dom_sid *owner_sid = NULL; + const struct dom_sid *group_sid = NULL; uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL); + struct security_token *token = fsp->conn->session_info->security_token; bool inherit_owner = lp_inherit_owner(SNUM(fsp->conn)); bool inheritable_components = false; + bool try_builtin_administrators = false; + const struct dom_sid *BA_U_sid = NULL; size_t size = 0; if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) { @@ -3478,10 +3483,42 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) } if (owner_sid == NULL) { - owner_sid = &fsp->conn->session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; + if (security_token_has_builtin_administrators(token)) { + try_builtin_administrators = true; + } else if (security_token_is_system(token)) { + try_builtin_administrators = true; + } + } + + if (try_builtin_administrators) { + struct unixid ids; + bool ok; + + ZERO_STRUCT(ids); + ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids); + if (ok) { + switch (ids.type) { + case ID_TYPE_BOTH: + BA_U_sid = &global_sid_Builtin_Administrators; + break; + case ID_TYPE_UID: + BA_U_sid = &global_sid_Builtin_Administrators; + break; + default: + break; + } + } + } + + if (owner_sid == NULL) { + owner_sid = BA_U_sid; + } + + if (owner_sid == NULL) { + owner_sid = &token->sids[PRIMARY_USER_SID_INDEX]; } if (group_sid == NULL) { - group_sid = &fsp->conn->session_info->security_token->sids[PRIMARY_GROUP_SID_INDEX]; + group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX]; } status = se_create_child_secdesc(frame, -- 1.7.9.5 From b3fe40cdaae197e85ca66b897a1e121f4e57d01c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Nov 2012 13:32:04 +0100 Subject: [PATCH 08/19] s3:smbd/open: try the primary sid (user) as group_sid if the token has just one sid Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 139232656a5de5f1c4694bbea8554a01c677081a) --- source3/smbd/open.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 1139386..ff00ddf 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3518,7 +3518,11 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) owner_sid = &token->sids[PRIMARY_USER_SID_INDEX]; } if (group_sid == NULL) { - group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX]; + if (token->num_sids == PRIMARY_GROUP_SID_INDEX) { + group_sid = &token->sids[PRIMARY_USER_SID_INDEX]; + } else { + group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX]; + } } status = se_create_child_secdesc(frame, -- 1.7.9.5 From 81907f204282ad08affeb16f2b33a6243d6f23fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Nov 2012 13:33:59 +0100 Subject: [PATCH 09/19] s3:smbd/open: fall back to Builtin_Administrators if SYSTEM doesn't map to a group Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 8fbe39d5134e136101425f9fc8d3d5080cbe25ba) --- source3/smbd/open.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/source3/smbd/open.c b/source3/smbd/open.c index ff00ddf..c5529ec 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -3442,6 +3442,10 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) bool inheritable_components = false; bool try_builtin_administrators = false; const struct dom_sid *BA_U_sid = NULL; + const struct dom_sid *BA_G_sid = NULL; + bool try_system = false; + const struct dom_sid *SY_U_sid = NULL; + const struct dom_sid *SY_G_sid = NULL; size_t size = 0; if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) { @@ -3487,6 +3491,16 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) try_builtin_administrators = true; } else if (security_token_is_system(token)) { try_builtin_administrators = true; + try_system = true; + } + } + + if (group_sid == NULL && + token->num_sids == PRIMARY_GROUP_SID_INDEX) + { + if (security_token_is_system(token)) { + try_builtin_administrators = true; + try_system = true; } } @@ -3500,10 +3514,38 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) switch (ids.type) { case ID_TYPE_BOTH: BA_U_sid = &global_sid_Builtin_Administrators; + BA_G_sid = &global_sid_Builtin_Administrators; break; case ID_TYPE_UID: BA_U_sid = &global_sid_Builtin_Administrators; break; + case ID_TYPE_GID: + BA_G_sid = &global_sid_Builtin_Administrators; + break; + default: + break; + } + } + } + + if (try_system) { + struct unixid ids; + bool ok; + + ZERO_STRUCT(ids); + ok = sids_to_unixids(&global_sid_System, 1, &ids); + if (ok) { + switch (ids.type) { + case ID_TYPE_BOTH: + SY_U_sid = &global_sid_System; + SY_G_sid = &global_sid_System; + break; + case ID_TYPE_UID: + SY_U_sid = &global_sid_System; + break; + case ID_TYPE_GID: + SY_G_sid = &global_sid_System; + break; default: break; } @@ -3515,6 +3557,18 @@ static NTSTATUS inherit_new_acl(files_struct *fsp) } if (owner_sid == NULL) { + owner_sid = SY_U_sid; + } + + if (group_sid == NULL) { + group_sid = SY_G_sid; + } + + if (try_system && group_sid == NULL) { + group_sid = BA_G_sid; + } + + if (owner_sid == NULL) { owner_sid = &token->sids[PRIMARY_USER_SID_INDEX]; } if (group_sid == NULL) { -- 1.7.9.5 From 1bce048a1bd03a89b1ddf280a0c761332369f8c5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 12:33:22 +0100 Subject: [PATCH 10/19] libcli/security: remove duplicate aces in se_create_child_secdesc() Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit cf60338ada9b1685aaa49a41cefbe1e14040a283) --- libcli/security/secdesc.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/libcli/security/secdesc.c b/libcli/security/secdesc.c index a3db1b6..d2c5833 100644 --- a/libcli/security/secdesc.c +++ b/libcli/security/secdesc.c @@ -679,6 +679,40 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx, talloc_free(frame); + /* + * remove duplicates + */ + for (i=1; i < new_ace_list_ndx;) { + struct security_ace *ai = &new_ace_list[i]; + unsigned int remaining, j; + bool remove = false; + + for (j=0; j < i; j++) { + struct security_ace *aj = &new_ace_list[j]; + + if (!sec_ace_equal(ai, aj)) { + continue; + } + + remove = true; + break; + } + + if (!remove) { + i++; + continue; + } + + new_ace_list_ndx--; + remaining = new_ace_list_ndx - i; + if (remaining == 0) { + ZERO_STRUCT(new_ace_list[i]); + continue; + } + memmove(&new_ace_list[i], &new_ace_list[i+1], + sizeof(new_ace_list[i]) * remaining); + } + /* Create child security descriptor to return */ if (new_ace_list_ndx) { new_dacl = make_sec_acl(ctx, -- 1.7.9.5 From 35f5efabd94f1dab7a2777ef14ab796015c280fe Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Nov 2012 13:52:53 +0100 Subject: [PATCH 11/19] s3:libsmb: add cli_{query,set}_security_descriptor() which take sec_info flags In order to set and get security_descriptors it's important to specify the sec_info flags. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 9afba14417ebb8e13623b62d3c81492629b92f29) --- source3/libsmb/clisecdesc.c | 56 ++++++++++++++++++++++++++++++------------- source3/libsmb/proto.h | 9 +++++++ 2 files changed, 49 insertions(+), 16 deletions(-) diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 04f661c..24da39d 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -21,8 +21,11 @@ #include "libsmb/libsmb.h" #include "../libcli/security/secdesc.h" -NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum, - TALLOC_CTX *mem_ctx, struct security_descriptor **sd) +NTSTATUS cli_query_security_descriptor(struct cli_state *cli, + uint16_t fnum, + uint32_t sec_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **sd) { uint8_t param[8]; uint8_t *rdata=NULL; @@ -31,7 +34,7 @@ NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum, struct security_descriptor *lsd; SIVAL(param, 0, fnum); - SIVAL(param, 4, 0x7); + SIVAL(param, 4, sec_info); status = cli_trans(talloc_tos(), cli, SMBnttrans, NULL, -1, /* name, fid */ @@ -71,14 +74,23 @@ NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum, return status; } +NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum, + TALLOC_CTX *mem_ctx, struct security_descriptor **sd) +{ + uint32_t sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL; + + return cli_query_security_descriptor(cli, fnum, sec_info, mem_ctx, sd); +} + /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ -NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, - const struct security_descriptor *sd) +NTSTATUS cli_set_security_descriptor(struct cli_state *cli, + uint16_t fnum, + uint32_t sec_info, + const struct security_descriptor *sd) { uint8_t param[8]; - uint32 sec_info = 0; uint8 *data; size_t len; NTSTATUS status; @@ -91,16 +103,7 @@ NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, } SIVAL(param, 0, fnum); - - if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) - sec_info |= SECINFO_DACL; - if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) - sec_info |= SECINFO_SACL; - if (sd->owner_sid) - sec_info |= SECINFO_OWNER; - if (sd->group_sid) - sec_info |= SECINFO_GROUP; - SSVAL(param, 4, sec_info); + SIVAL(param, 4, sec_info); status = cli_trans(talloc_tos(), cli, SMBnttrans, NULL, -1, /* name, fid */ @@ -119,3 +122,24 @@ NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, } return status; } + +NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, + const struct security_descriptor *sd) +{ + uint32_t sec_info = 0; + + if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) { + sec_info |= SECINFO_DACL; + } + if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) { + sec_info |= SECINFO_SACL; + } + if (sd->owner_sid) { + sec_info |= SECINFO_OWNER; + } + if (sd->group_sid) { + sec_info |= SECINFO_GROUP; + } + + return cli_set_security_descriptor(cli, fnum, sec_info, sd); +} diff --git a/source3/libsmb/proto.h b/source3/libsmb/proto.h index e6d0ce8..f186fee 100644 --- a/source3/libsmb/proto.h +++ b/source3/libsmb/proto.h @@ -792,8 +792,17 @@ NTSTATUS cli_push(struct cli_state *cli, uint16_t fnum, uint16_t mode, /* The following definitions come from libsmb/clisecdesc.c */ +NTSTATUS cli_query_security_descriptor(struct cli_state *cli, + uint16_t fnum, + uint32_t sec_info, + TALLOC_CTX *mem_ctx, + struct security_descriptor **sd); NTSTATUS cli_query_secdesc(struct cli_state *cli, uint16_t fnum, TALLOC_CTX *mem_ctx, struct security_descriptor **sd); +NTSTATUS cli_set_security_descriptor(struct cli_state *cli, + uint16_t fnum, + uint32_t sec_info, + const struct security_descriptor *sd); NTSTATUS cli_set_secdesc(struct cli_state *cli, uint16_t fnum, const struct security_descriptor *sd); -- 1.7.9.5 From 72aa4db46b4b45b3c02953356e3fb29db7272ba2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 30 Nov 2012 14:36:07 +0100 Subject: [PATCH 12/19] s3:smbcacls: add --query-security-info and --set-security-info options This allows the caller to specify the security_information flags. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 0e2e3ff5e864115495be68040959838e2835e260) --- source3/utils/smbcacls.c | 65 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 10 deletions(-) diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 3d18bee..9eccede 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -41,6 +41,8 @@ static int test_args; static int numeric; static int sddl; +static int query_sec_info = -1; +static int set_sec_info = -1; static const char *domain_sid = NULL; @@ -835,11 +837,27 @@ static struct security_descriptor *get_secdesc(struct cli_state *cli, const char uint16_t fnum = (uint16_t)-1; struct security_descriptor *sd; NTSTATUS status; + uint32_t sec_info; + uint32_t desired_access = 0; - /* The desired access below is the only one I could find that works - with NT4, W2KP and Samba */ + if (query_sec_info == -1) { + sec_info = SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL; + } else { + sec_info = query_sec_info; + } - status = cli_ntcreate(cli, filename, 0, CREATE_ACCESS_READ, + if (sec_info & (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL)) { + desired_access |= SEC_STD_READ_CONTROL; + } + if (sec_info & SECINFO_SACL) { + desired_access |= SEC_FLAG_SYSTEM_SECURITY; + } + + if (desired_access == 0) { + desired_access |= SEC_STD_READ_CONTROL; + } + + status = cli_ntcreate(cli, filename, 0, desired_access, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0, &fnum); if (!NT_STATUS_IS_OK(status)) { @@ -847,7 +865,8 @@ static struct security_descriptor *get_secdesc(struct cli_state *cli, const char return NULL; } - status = cli_query_secdesc(cli, fnum, talloc_tos(), &sd); + status = cli_query_security_descriptor(cli, fnum, sec_info, + talloc_tos(), &sd); cli_close(cli, fnum); @@ -869,16 +888,36 @@ static bool set_secdesc(struct cli_state *cli, const char *filename, bool result=true; NTSTATUS status; uint32_t desired_access = 0; + uint32_t sec_info; + + if (set_sec_info == -1) { + sec_info = 0; + + if (sd->dacl || (sd->type & SEC_DESC_DACL_PRESENT)) { + sec_info |= SECINFO_DACL; + } + if (sd->sacl || (sd->type & SEC_DESC_SACL_PRESENT)) { + sec_info |= SECINFO_SACL; + } + if (sd->owner_sid) { + sec_info |= SECINFO_OWNER; + } + if (sd->group_sid) { + sec_info |= SECINFO_GROUP; + } + } else { + sec_info = set_sec_info; + } /* Make the desired_access more specific. */ - if (sd->dacl) { - desired_access |= WRITE_DAC_ACCESS; + if (sec_info & SECINFO_DACL) { + desired_access |= SEC_STD_WRITE_DAC; } - if (sd->sacl) { + if (sec_info & SECINFO_SACL) { desired_access |= SEC_FLAG_SYSTEM_SECURITY; } - if (sd->owner_sid || sd->group_sid) { - desired_access |= WRITE_OWNER_ACCESS; + if (sec_info & (SECINFO_OWNER | SECINFO_GROUP)) { + desired_access |= SEC_STD_WRITE_OWNER; } status = cli_ntcreate(cli, filename, 0, @@ -890,7 +929,7 @@ static bool set_secdesc(struct cli_state *cli, const char *filename, return false; } - status = cli_set_secdesc(cli, fnum, sd); + status = cli_set_security_descriptor(cli, fnum, sec_info, sd); if (!NT_STATUS_IS_OK(status)) { printf("ERROR: security description set failed: %s\n", nt_errstr(status)); @@ -1339,6 +1378,12 @@ static struct cli_state *connect_one(struct user_auth_info *auth_info, { "inherit", 'I', POPT_ARG_STRING, NULL, 'I', "Inherit allow|remove|copy" }, { "numeric", 0, POPT_ARG_NONE, &numeric, 1, "Don't resolve sids or masks to names" }, { "sddl", 0, POPT_ARG_NONE, &sddl, 1, "Output and input acls in sddl format" }, + { "query-security-info", 0, POPT_ARG_INT, &query_sec_info, 1, + "The security-info flags for queries" + }, + { "set-security-info", 0, POPT_ARG_INT, &set_sec_info, 1, + "The security-info flags for modifications" + }, { "test-args", 't', POPT_ARG_NONE, &test_args, 1, "Test arguments"}, { "domain-sid", 0, POPT_ARG_STRING, &domain_sid, 0, "Domain SID for sddl", "SID"}, POPT_COMMON_SAMBA -- 1.7.9.5 From 492d11662079c35be9a1cadf3a22464870ddc528 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Dec 2012 08:56:57 +0100 Subject: [PATCH 13/19] s4:libcli/finddcs_cldap: try all NBT#1C addresses Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit c4d51d8d17f04583868f1fdc82322b26bcb1c7a0) --- source4/libcli/finddcs_cldap.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/source4/libcli/finddcs_cldap.c b/source4/libcli/finddcs_cldap.c index 38e828f..a7162f8 100644 --- a/source4/libcli/finddcs_cldap.c +++ b/source4/libcli/finddcs_cldap.c @@ -53,7 +53,7 @@ static bool finddcs_cldap_nbt_lookup(struct finddcs_cldap_state *state, struct finddcs *io, struct resolve_context *resolve_ctx, struct tevent_context *event_ctx); -static void finddcs_cldap_name_resolved(struct composite_context *ctx); +static void finddcs_cldap_nbt_resolved(struct composite_context *ctx); static void finddcs_cldap_next_server(struct finddcs_cldap_state *state); static bool finddcs_cldap_ipaddress(struct finddcs_cldap_state *state, struct finddcs *io); @@ -200,7 +200,7 @@ static bool finddcs_cldap_nbt_lookup(struct finddcs_cldap_state *state, if (tevent_req_nomem(creq, state->req)) { return false; } - creq->async.fn = finddcs_cldap_name_resolved; + creq->async.fn = finddcs_cldap_nbt_resolved; creq->async.private_data = state; return true; } @@ -315,27 +315,23 @@ static void finddcs_cldap_netlogon_replied(struct tevent_req *subreq) /* handle NBT name lookup reply */ -static void finddcs_cldap_name_resolved(struct composite_context *ctx) +static void finddcs_cldap_nbt_resolved(struct composite_context *ctx) { struct finddcs_cldap_state *state = talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state); - const char *address; NTSTATUS status; + unsigned i; - status = resolve_name_recv(ctx, state, &address); + status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses); if (tevent_req_nterror(state->req, status)) { DEBUG(2,("finddcs: No matching NBT <1c> server found\n")); return; } - DEBUG(4,("finddcs: Found NBT <1c> server at %s\n", address)); - - state->srv_addresses = talloc_array(state, const char *, 2); - if (tevent_req_nomem(state->srv_addresses, state->req)) { - return; + for (i=0; state->srv_addresses[i]; i++) { + DEBUG(4,("finddcs: NBT <1c> response %u at '%s'\n", + i, state->srv_addresses[i])); } - state->srv_addresses[0] = address; - state->srv_addresses[1] = NULL; state->srv_address_index = 0; -- 1.7.9.5 From 21fd5c0ef3ded100d56eaa5ec89c16f274cd6b6b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 1 Dec 2012 09:14:19 +0100 Subject: [PATCH 14/19] s4:libcli/finddcs_cldap: allow io->in.server_address as hostname Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit a42c49c93acb9e480b6e174f56fb75ae0524b984) --- source4/libcli/finddcs_cldap.c | 61 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/source4/libcli/finddcs_cldap.c b/source4/libcli/finddcs_cldap.c index a7162f8..bf8da4e 100644 --- a/source4/libcli/finddcs_cldap.c +++ b/source4/libcli/finddcs_cldap.c @@ -29,6 +29,7 @@ #include "lib/util/tevent_ntstatus.h" #include "lib/tsocket/tsocket.h" #include "libcli/composite/composite.h" +#include "lib/util/util_net.h" struct finddcs_cldap_state { struct tevent_context *ev; @@ -54,6 +55,11 @@ static bool finddcs_cldap_nbt_lookup(struct finddcs_cldap_state *state, struct resolve_context *resolve_ctx, struct tevent_context *event_ctx); static void finddcs_cldap_nbt_resolved(struct composite_context *ctx); +static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state, + struct finddcs *io, + struct resolve_context *resolve_ctx, + struct tevent_context *event_ctx); +static void finddcs_cldap_name_resolved(struct composite_context *ctx); static void finddcs_cldap_next_server(struct finddcs_cldap_state *state); static bool finddcs_cldap_ipaddress(struct finddcs_cldap_state *state, struct finddcs *io); @@ -97,9 +103,17 @@ struct tevent_req *finddcs_cldap_send(TALLOC_CTX *mem_ctx, } if (io->in.server_address) { - DEBUG(4,("finddcs: searching for a DC by IP %s\n", io->in.server_address)); - if (!finddcs_cldap_ipaddress(state, io)) { - return tevent_req_post(req, event_ctx); + if (is_ipaddress(io->in.server_address)) { + DEBUG(4,("finddcs: searching for a DC by IP %s\n", + io->in.server_address)); + if (!finddcs_cldap_ipaddress(state, io)) { + return tevent_req_post(req, event_ctx); + } + } else { + if (!finddcs_cldap_name_lookup(state, io, resolve_ctx, + event_ctx)) { + return tevent_req_post(req, event_ctx); + } } } else if (io->in.domain_name) { if (strchr(state->domain_name, '.')) { @@ -205,6 +219,24 @@ static bool finddcs_cldap_nbt_lookup(struct finddcs_cldap_state *state, return true; } +static bool finddcs_cldap_name_lookup(struct finddcs_cldap_state *state, + struct finddcs *io, + struct resolve_context *resolve_ctx, + struct tevent_context *event_ctx) +{ + struct composite_context *creq; + struct nbt_name name; + + make_nbt_name(&name, io->in.server_address, NBT_NAME_SERVER); + creq = resolve_name_send(resolve_ctx, state, &name, event_ctx); + if (tevent_req_nomem(creq, state->req)) { + return false; + } + creq->async.fn = finddcs_cldap_name_resolved; + creq->async.private_data = state; + return true; +} + /* fire off a CLDAP query to the next server */ @@ -312,6 +344,29 @@ static void finddcs_cldap_netlogon_replied(struct tevent_req *subreq) tevent_req_done(state->req); } +static void finddcs_cldap_name_resolved(struct composite_context *ctx) +{ + struct finddcs_cldap_state *state = + talloc_get_type(ctx->async.private_data, struct finddcs_cldap_state); + NTSTATUS status; + unsigned i; + + status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses); + if (tevent_req_nterror(state->req, status)) { + DEBUG(2,("finddcs: No matching server found\n")); + return; + } + + for (i=0; state->srv_addresses[i]; i++) { + DEBUG(4,("finddcs: response %u at '%s'\n", + i, state->srv_addresses[i])); + } + + state->srv_address_index = 0; + + finddcs_cldap_next_server(state); +} + /* handle NBT name lookup reply */ -- 1.7.9.5 From 724ba37b1f4b567f37d6f9c5d2e31c451a8b4059 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 09:31:12 +0100 Subject: [PATCH 15/19] s4:samba-tool/gpo: use the dns_domain from the server when creating gpos Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit a1a525e2a9b0bc20e3e06695fbcbdf0d172839a1) --- source4/scripting/python/samba/netcmd/gpo.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index cc63819..5169085 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -42,6 +42,8 @@ from samba import policy from samba import smb import uuid from samba.ntacls import dsacl2fsacl +from samba.dcerpc import nbt +from samba.net import Net def samdb_connect(ctx): @@ -892,12 +894,22 @@ class cmd_create(Command): self.lp = sambaopts.get_loadparm() self.creds = credopts.get_credentials(self.lp, fallback_machine=True) + net = Net(creds=self.creds, lp=self.lp) + # We need to know writable DC to setup SMB connection if H and H.startswith('ldap://'): dc_hostname = H[7:] self.url = H + flags = (nbt.NBT_SERVER_LDAP | + nbt.NBT_SERVER_DS | + nbt.NBT_SERVER_WRITABLE) + cldap_ret = net.finddc(address=dc_hostname, flags=flags) else: - dc_hostname = netcmd_finddc(self.lp, self.creds) + flags = (nbt.NBT_SERVER_LDAP | + nbt.NBT_SERVER_DS | + nbt.NBT_SERVER_WRITABLE) + cldap_ret = net.finddc(domain=self.lp.get('realm'), flags=flags) + dc_hostname = cldap_ret.pdc_dns_name self.url = dc_url(self.lp, self.creds, dc=dc_hostname) samdb_connect(self) @@ -909,7 +921,7 @@ class cmd_create(Command): # Create new GUID guid = str(uuid.uuid4()) gpo = "{%s}" % guid.upper() - realm = self.lp.get('realm') + realm = cldap_ret.dns_domain unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (realm, realm, gpo) # Create GPT -- 1.7.9.5 From eb39410861c21eaa625a70e02ed5e8c5ee4f571c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 09:31:12 +0100 Subject: [PATCH 16/19] s4:samba-tool/gpo: use 'gPCFileSysPath' when deleting gpos Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit dde7eb0d82e9b980c9b08fb4590b7e77bda0c76b) --- source4/scripting/python/samba/netcmd/gpo.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 5169085..26b2e8c 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -1048,13 +1048,11 @@ class cmd_del(Command): # Check if valid GPO try: - get_gpo_info(self.samdb, gpo=gpo)[0] + msg = get_gpo_info(self.samdb, gpo=gpo)[0] + unc_path = msg['gPCFileSysPath'][0] except Exception: raise CommandError("GPO '%s' does not exist" % gpo) - realm = self.lp.get('realm') - unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (realm, realm, gpo) - # Connect to DC over SMB [dom_name, service, sharepath] = parse_unc(unc_path) try: -- 1.7.9.5 From 198746293b53f90ad7528863abf5df904229c700 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 09:31:12 +0100 Subject: [PATCH 17/19] s4:samba-tool/gpo: fix the operation order when creating gpos We should do it like the windows GUI. 1. create the LDAP objects 2. query the security_descriptor of the groupPolicyContainer 3. create the gPCFileSysPath via smb 4. set the security_descriptor of gPCFileSysPath 5. copy the files and directories into gPCFileSysPath 6. modify the groupPolicyContainer and link gPCFileSysPath Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit d48d0c5bbf70394dfc6ab44ef124582fd836695f) --- source4/scripting/python/samba/netcmd/gpo.py | 33 ++++++++++++++++---------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/source4/scripting/python/samba/netcmd/gpo.py b/source4/scripting/python/samba/netcmd/gpo.py index 26b2e8c..23b562e 100644 --- a/source4/scripting/python/samba/netcmd/gpo.py +++ b/source4/scripting/python/samba/netcmd/gpo.py @@ -962,34 +962,25 @@ class cmd_create(Command): m = ldb.Message() m.dn = gpo_dn m['a01'] = ldb.MessageElement("groupPolicyContainer", ldb.FLAG_MOD_ADD, "objectClass") - m['a02'] = ldb.MessageElement(displayname, ldb.FLAG_MOD_ADD, "displayName") - m['a03'] = ldb.MessageElement(unc_path, ldb.FLAG_MOD_ADD, "gPCFileSysPath") - m['a04'] = ldb.MessageElement("0", ldb.FLAG_MOD_ADD, "flags") - m['a05'] = ldb.MessageElement("0", ldb.FLAG_MOD_ADD, "versionNumber") - m['a06'] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_ADD, "showInAdvancedViewOnly") - m['a07'] = ldb.MessageElement("2", ldb.FLAG_MOD_ADD, "gpcFunctionalityVersion") self.samdb.add(m) # Add cn=User,cn= m = ldb.Message() m.dn = ldb.Dn(self.samdb, "CN=User,%s" % str(gpo_dn)) m['a01'] = ldb.MessageElement("container", ldb.FLAG_MOD_ADD, "objectClass") - m['a02'] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_ADD, "showInAdvancedViewOnly") self.samdb.add(m) # Add cn=Machine,cn= m = ldb.Message() m.dn = ldb.Dn(self.samdb, "CN=Machine,%s" % str(gpo_dn)) m['a01'] = ldb.MessageElement("container", ldb.FLAG_MOD_ADD, "objectClass") - m['a02'] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_ADD, "showInAdvancedViewOnly") self.samdb.add(m) - # Copy GPO files over SMB - create_directory_hier(conn, sharepath) - copy_directory_local_to_remote(conn, gpodir, sharepath) - # Get new security descriptor - msg = get_gpo_info(self.samdb, gpo=gpo)[0] + ds_sd_flags = ( security.SECINFO_OWNER | + security.SECINFO_GROUP | + security.SECINFO_DACL ) + msg = get_gpo_info(self.samdb, gpo=gpo, sd_flags=ds_sd_flags)[0] ds_sd_ndr = msg['nTSecurityDescriptor'][0] ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl() @@ -998,12 +989,28 @@ class cmd_create(Command): sddl = dsacl2fsacl(ds_sd, domain_sid) fs_sd = security.descriptor.from_sddl(sddl, domain_sid) + # Copy GPO directory + create_directory_hier(conn, sharepath) + # Set ACL sio = ( security.SECINFO_OWNER | security.SECINFO_GROUP | security.SECINFO_DACL | security.SECINFO_PROTECTED_DACL ) conn.set_acl(sharepath, fs_sd, sio) + + # Copy GPO files over SMB + copy_directory_local_to_remote(conn, gpodir, sharepath) + + m = ldb.Message() + m.dn = gpo_dn + m['a02'] = ldb.MessageElement(displayname, ldb.FLAG_MOD_REPLACE, "displayName") + m['a03'] = ldb.MessageElement(unc_path, ldb.FLAG_MOD_REPLACE, "gPCFileSysPath") + m['a05'] = ldb.MessageElement("0", ldb.FLAG_MOD_REPLACE, "versionNumber") + m['a07'] = ldb.MessageElement("2", ldb.FLAG_MOD_REPLACE, "gpcFunctionalityVersion") + m['a04'] = ldb.MessageElement("0", ldb.FLAG_MOD_REPLACE, "flags") + controls=["permissive_modify:0"] + self.samdb.modify(m, controls=controls) except Exception: self.samdb.transaction_cancel() raise -- 1.7.9.5 From a9a521f1a42fedf0177e2893cd5f228e82d93928 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 09:28:23 +0100 Subject: [PATCH 18/19] s4:python/ntacl: allow string or objects for sd/sid in setntacl() Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 06f026368e5b657394bb9e681c3d0184104bc120) --- source4/scripting/python/samba/ntacls.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py index 8992b61..d86c517 100644 --- a/source4/scripting/python/samba/ntacls.py +++ b/source4/scripting/python/samba/ntacls.py @@ -85,8 +85,19 @@ def getntacl(lp, file, backend=None, eadbfile=None, direct_db_access=True): def setntacl(lp, file, sddl, domsid, backend=None, eadbfile=None, use_ntvfs=True, skip_invalid_chown=False, passdb=None): - sid = security.dom_sid(domsid) - sd = security.descriptor.from_sddl(sddl, sid) + assert(isinstance(domsid, str) or isinstance(domsid, security.dom_sid)) + if isinstance(domsid, str): + sid = security.dom_sid(domsid) + elif isinstance(domsid, security.dom_sid): + sid = domsid + domsid = str(sid) + + assert(isinstance(sddl, str) or isinstance(sddl, security.descriptor)) + if isinstance(sddl, str): + sd = security.descriptor.from_sddl(sddl, sid) + elif isinstance(sddl, security.descriptor): + sd = sddl + sddl = sd.as_sddl(sid) if not use_ntvfs and skip_invalid_chown: # Check if the owner can be resolved as a UID @@ -103,7 +114,7 @@ def setntacl(lp, file, sddl, domsid, backend=None, eadbfile=None, use_ntvfs=True if ((admin_type == idmap.ID_TYPE_UID) or (admin_type == idmap.ID_TYPE_BOTH)): # Set it, changing the owner to 'administrator' rather than domain admins - sd2 = security.descriptor.from_sddl(sddl, sid) + sd2 = sd sd2.owner_sid = administrator smbd.set_nt_acl(file, security.SECINFO_OWNER |security.SECINFO_GROUP | security.SECINFO_DACL | security.SECINFO_SACL, sd2) -- 1.7.9.5 From a3e9e55957534870451cf19db65350ccab0e9f64 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Nov 2012 09:57:44 +0100 Subject: [PATCH 19/19] s4:python/ntacl: add 'as_sddl' option to dsacl2fsacl() This allows the caller to ask for a security.descriptor instead of sddl by passing 'as_sddl=False'. Signed-off-by: Stefan Metzmacher Reviewed-by: Michael Adam (cherry picked from commit 6f71071381ead9976f4a6d296c9a1ade385484e0) --- source4/scripting/python/samba/ntacls.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source4/scripting/python/samba/ntacls.py b/source4/scripting/python/samba/ntacls.py index d86c517..b89e9e9 100644 --- a/source4/scripting/python/samba/ntacls.py +++ b/source4/scripting/python/samba/ntacls.py @@ -209,7 +209,7 @@ def ldapmask2filemask(ldm): return filemask -def dsacl2fsacl(dssddl, sid): +def dsacl2fsacl(dssddl, sid, as_sddl=True): """ This function takes an the SDDL representation of a DS @@ -234,4 +234,7 @@ def dsacl2fsacl(dssddl, sid): ace.access_mask = ldapmask2filemask(ace.access_mask) fdescr.dacl_add(ace) + if not as_sddl: + return fdescr + return fdescr.as_sddl(sid) -- 1.7.9.5