[SCM] SAMBA-CTDB repository - branch v3-4-ctdb updated - 3648046962a7cce0f9caeef6bd199ab1878bfdc1

Michael Adam obnox at samba.org
Tue Mar 16 01:37:35 MDT 2010


The branch, v3-4-ctdb has been updated
       via  3648046962a7cce0f9caeef6bd199ab1878bfdc1 (commit)
       via  a885950fbfa049bc9b5474a42940430e1d6d6f6a (commit)
       via  9a9a70f62e31e03d427275fabc2f00bb418ffa8d (commit)
       via  2a684ee14be97e4d8e4b5a5f9ca59dafa439097f (commit)
       via  bd5c0f1b09598d817be854e7df9369a98a3fdf9f (commit)
       via  734008358b7df2db2cea9f71a04196cf14223211 (commit)
       via  72f4af8cc539674560fe683a7701637f4fac9dfe (commit)
       via  617d711e0b86704b918483a8161410ac1bb80cd8 (commit)
       via  8a8e4a620636b098ae56f46be6112d9e68b1c665 (commit)
       via  40df775c85e7d9cbca75a98bf4894a21e65c950d (commit)
       via  7193d06749bc52cd69dec6481674682ed1dc7bbd (commit)
       via  5501720c6f3a0fdb4f02ee388fdf3d9fdb06fe82 (commit)
      from  51f1e41076cfddb52fdeebb6f2b662cdc91553be (commit)

http://gitweb.samba.org/?p=obnox/samba-ctdb.git;a=shortlog;h=v3-4-ctdb


- Log -----------------------------------------------------------------
commit 3648046962a7cce0f9caeef6bd199ab1878bfdc1
Author: Michael Adam <obnox at samba.org>
Date:   Tue Mar 2 14:43:53 2010 +0100

    s3:net: add a command "net registry setsd_sdd"
    
    This permits to set the security descriptor of a registry
    key from the unix command line.
    
    Michael
    (cherry picked from commit 27ae935a8df409ce7557bd369250fa450120fdfe)

commit a885950fbfa049bc9b5474a42940430e1d6d6f6a
Author: Michael Adam <obnox at samba.org>
Date:   Fri Feb 26 09:37:45 2010 +0100

    s3:net: add new subcommand "net registry getsd_sddl" to print secdesc in sddl format
    
    Michael
    (cherry picked from commit caa27bb165a69766585ec4a13a6c09fa774d3b48)

commit 9a9a70f62e31e03d427275fabc2f00bb418ffa8d
Author: Michael Adam <obnox at samba.org>
Date:   Fri Feb 26 09:31:03 2010 +0100

    s3:net: refactor getting of secdesc out of net_registry_getsd()
    
    New net_registry_getsd_internal does the work(),
    net_registry_getsd() just prints the result.
    This in preparation to add support for other output formats
    than the currently used display_sec_desc().
    
    Michael

commit 2a684ee14be97e4d8e4b5a5f9ca59dafa439097f
Author: Michael Adam <obnox at samba.org>
Date:   Tue Aug 11 23:35:48 2009 +0200

    s3:smbcacls: forbid change of debug level from config file
    
    Michael
    (cherry picked from commit a038f1e05b8b7acb5e99257e59178e1ece4ce156)

commit bd5c0f1b09598d817be854e7df9369a98a3fdf9f
Author: Michael Adam <obnox at samba.org>
Date:   Mon Mar 15 12:16:52 2010 +0100

    s3:smbcacls: also honour the "--sddl" flag when setting ACLs.
    
    Michael

commit 734008358b7df2db2cea9f71a04196cf14223211
Author: Michael Adam <obnox at samba.org>
Date:   Sun Feb 28 22:20:03 2010 +0100

    s3:smbcacls: add switch "--sddl" to output acls as sddl encoded strings
    (cherry picked from commit 9cea4d5969d3061689e7399e0a97f7f83ed31976)

commit 72f4af8cc539674560fe683a7701637f4fac9dfe
Author: Michael Adam <obnox at samba.org>
Date:   Sun Feb 28 22:15:23 2010 +0100

    s3: build sddl.c in samba3

commit 617d711e0b86704b918483a8161410ac1bb80cd8
Author: Michael Adam <obnox at samba.org>
Date:   Sun Feb 28 22:01:49 2010 +0100

    libcli/security: fix sddl.c to be able to build it from source3
    (cherry picked from commit f37030b33afa989adaafa6d3d02751bd286f879b)

commit 8a8e4a620636b098ae56f46be6112d9e68b1c665
Author: Michael Adam <obnox at samba.org>
Date:   Fri Feb 26 18:32:21 2010 +0100

    s4:move the sddl code down to the top level
    
    Michael

commit 40df775c85e7d9cbca75a98bf4894a21e65c950d
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 12 15:48:35 2010 +0100

    s3: Add "net registry increment"
    
    A convenience function to increment a DWORD value under a (cluster-wide) lock

commit 7193d06749bc52cd69dec6481674682ed1dc7bbd
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 12 14:22:54 2010 +0100

    s3: Add "g_lock_do" as a convenience wrapper function

commit 5501720c6f3a0fdb4f02ee388fdf3d9fdb06fe82
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Mar 12 12:12:25 2010 +0100

    s3: Actually use mem_ctx in net_g_lock_init()

-----------------------------------------------------------------------

Summary of changes:
 libcli/security/config.mk          |    2 +-
 libcli/security/sddl.c             |  598 ++++++++++++++++++++++++++++++++++++
 libcli/security/sddl.h             |   32 ++
 source3/Makefile.in                |    1 +
 source3/include/g_lock.h           |    4 +
 source3/include/includes.h         |    1 +
 source3/lib/g_lock.c               |   64 ++++
 source3/utils/net_g_lock.c         |   55 ++--
 source3/utils/net_registry.c       |  271 ++++++++++++++++-
 source3/utils/smbcacls.c           |   19 +-
 source4/libcli/security/config.mk  |    2 +-
 source4/libcli/security/sddl.c     |  598 ------------------------------------
 source4/libcli/security/security.h |    1 +
 13 files changed, 1007 insertions(+), 641 deletions(-)
 create mode 100644 libcli/security/sddl.c
 create mode 100644 libcli/security/sddl.h
 delete mode 100644 source4/libcli/security/sddl.c


Changeset truncated at 500 lines:

diff --git a/libcli/security/config.mk b/libcli/security/config.mk
index 56d8e13..501857c 100644
--- a/libcli/security/config.mk
+++ b/libcli/security/config.mk
@@ -2,4 +2,4 @@
 PRIVATE_DEPENDENCIES = TALLOC
 
 LIBSECURITY_COMMON_OBJ_FILES = $(addprefix $(libclicommonsrcdir)/security/, \
-					dom_sid.o)
+					dom_sid.o sddl.o)
diff --git a/libcli/security/sddl.c b/libcli/security/sddl.c
new file mode 100644
index 0000000..1c49409
--- /dev/null
+++ b/libcli/security/sddl.c
@@ -0,0 +1,598 @@
+/* 
+   Unix SMB/CIFS implementation.
+
+   security descriptor description language functions
+
+   Copyright (C) Andrew Tridgell 		2005
+      
+   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 <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libcli/security/dom_sid.h"
+#include "librpc/gen_ndr/ndr_misc.h"
+#include "system/locale.h"
+
+struct flag_map {
+	const char *name;
+	uint32_t flag;
+};
+
+/*
+  map a series of letter codes into a uint32_t
+*/
+static bool sddl_map_flags(const struct flag_map *map, const char *str, 
+			   uint32_t *flags, size_t *len)
+{
+	const char *str0 = str;
+	if (len) *len = 0;
+	*flags = 0;
+	while (str[0] && isupper(str[0])) {
+		int i;
+		for (i=0;map[i].name;i++) {
+			size_t l = strlen(map[i].name);
+			if (strncmp(map[i].name, str, l) == 0) {
+				*flags |= map[i].flag;
+				str += l;
+				if (len) *len += l;
+				break;
+			}
+		}
+		if (map[i].name == NULL) {
+			DEBUG(1, ("Unknown flag - %s in %s\n", str, str0));
+			return false;
+		}
+	}
+	return true;
+}
+
+/*
+  a mapping between the 2 letter SID codes and sid strings
+*/
+static const struct {
+	const char *code;
+	const char *sid;
+	uint32_t rid;
+} sid_codes[] = {
+	{ "AO", SID_BUILTIN_ACCOUNT_OPERATORS },
+	{ "BA", SID_BUILTIN_ADMINISTRATORS },
+	{ "RU", SID_BUILTIN_PREW2K },
+	{ "PO", SID_BUILTIN_PRINT_OPERATORS },
+	{ "RS", SID_BUILTIN_RAS_SERVERS },
+
+	{ "AU", SID_NT_AUTHENTICATED_USERS },
+	{ "SY", SID_NT_SYSTEM },
+	{ "PS", SID_NT_SELF },
+	{ "WD", SID_WORLD },
+	{ "ED", SID_NT_ENTERPRISE_DCS },
+
+	{ "CO", SID_CREATOR_OWNER },
+	{ "CG", SID_CREATOR_GROUP },
+
+	{ "DA", NULL, DOMAIN_RID_ADMINS },
+	{ "EA", NULL, DOMAIN_RID_ENTERPRISE_ADMINS },
+	{ "DD", NULL, DOMAIN_RID_DCS },
+	{ "DU", NULL, DOMAIN_RID_USERS },
+	{ "CA", NULL, DOMAIN_RID_CERT_ADMINS },
+};
+
+/*
+  decode a SID
+  It can either be a special 2 letter code, or in S-* format
+*/
+static struct dom_sid *sddl_decode_sid(TALLOC_CTX *mem_ctx, const char **sddlp,
+				       const struct dom_sid *domain_sid)
+{
+	const char *sddl = (*sddlp);
+	int i;
+
+	/* see if its in the numeric format */
+	if (strncmp(sddl, "S-", 2) == 0) {
+		struct dom_sid *sid;
+		char *sid_str;
+		size_t len = strspn(sddl+2, "-0123456789");
+		sid_str = talloc_strndup(mem_ctx, sddl, len+2);
+		if (!sid_str) {
+			return NULL;
+		}
+		(*sddlp) += len+2;
+		sid = dom_sid_parse_talloc(mem_ctx, sid_str);
+		talloc_free(sid_str);
+		return sid;
+	}
+
+	/* now check for one of the special codes */
+	for (i=0;i<ARRAY_SIZE(sid_codes);i++) {
+		if (strncmp(sid_codes[i].code, sddl, 2) == 0) break;
+	}
+	if (i == ARRAY_SIZE(sid_codes)) {
+		DEBUG(1,("Unknown sddl sid code '%2.2s'\n", sddl));
+		return NULL;
+	}
+
+	(*sddlp) += 2;
+
+	if (sid_codes[i].sid == NULL) {
+		return dom_sid_add_rid(mem_ctx, domain_sid, sid_codes[i].rid);
+	}
+
+	return dom_sid_parse_talloc(mem_ctx, sid_codes[i].sid);
+}
+
+static const struct flag_map ace_types[] = {
+	{ "AU", SEC_ACE_TYPE_SYSTEM_AUDIT },
+	{ "AL", SEC_ACE_TYPE_SYSTEM_ALARM },
+	{ "OA", SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT },
+	{ "OD", SEC_ACE_TYPE_ACCESS_DENIED_OBJECT },
+	{ "OU", SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT },
+	{ "OL", SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT },
+	{ "A",  SEC_ACE_TYPE_ACCESS_ALLOWED },
+	{ "D",  SEC_ACE_TYPE_ACCESS_DENIED },
+	{ NULL, 0 }
+};
+
+static const struct flag_map ace_flags[] = {
+	{ "OI", SEC_ACE_FLAG_OBJECT_INHERIT },
+	{ "CI", SEC_ACE_FLAG_CONTAINER_INHERIT },
+	{ "NP", SEC_ACE_FLAG_NO_PROPAGATE_INHERIT },
+	{ "IO", SEC_ACE_FLAG_INHERIT_ONLY },
+	{ "ID", SEC_ACE_FLAG_INHERITED_ACE },
+	{ "SA", SEC_ACE_FLAG_SUCCESSFUL_ACCESS },
+	{ "FA", SEC_ACE_FLAG_FAILED_ACCESS },
+	{ NULL, 0 },
+};
+
+static const struct flag_map ace_access_mask[] = {
+	{ "RP", SEC_ADS_READ_PROP },
+	{ "WP", SEC_ADS_WRITE_PROP },
+	{ "CR", SEC_ADS_CONTROL_ACCESS },
+	{ "CC", SEC_ADS_CREATE_CHILD },
+	{ "DC", SEC_ADS_DELETE_CHILD },
+	{ "LC", SEC_ADS_LIST },
+	{ "LO", SEC_ADS_LIST_OBJECT },
+	{ "RC", SEC_STD_READ_CONTROL },
+	{ "WO", SEC_STD_WRITE_OWNER },
+	{ "WD", SEC_STD_WRITE_DAC },
+	{ "SD", SEC_STD_DELETE },
+	{ "DT", SEC_ADS_DELETE_TREE },
+	{ "SW", SEC_ADS_SELF_WRITE },
+	{ "GA", SEC_GENERIC_ALL },
+	{ "GR", SEC_GENERIC_READ },
+	{ "GW", SEC_GENERIC_WRITE },
+	{ "GX", SEC_GENERIC_EXECUTE },
+	{ NULL, 0 }
+};
+
+/*
+  decode an ACE
+  return true on success, false on failure
+  note that this routine modifies the string
+*/
+static bool sddl_decode_ace(TALLOC_CTX *mem_ctx, struct security_ace *ace, char *str,
+			    const struct dom_sid *domain_sid)
+{
+	const char *tok[6];
+	const char *s;
+	int i;
+	uint32_t v;
+	struct dom_sid *sid;
+
+	ZERO_STRUCTP(ace);
+
+	/* parse out the 6 tokens */
+	tok[0] = str;
+	for (i=0;i<5;i++) {
+		char *ptr = strchr(str, ';');
+		if (ptr == NULL) return false;
+		*ptr = 0;
+		str = ptr+1;
+		tok[i+1] = str;
+	}
+
+	/* parse ace type */
+	if (!sddl_map_flags(ace_types, tok[0], &v, NULL)) {
+		return false;
+	}
+	ace->type = v;
+
+	/* ace flags */
+	if (!sddl_map_flags(ace_flags, tok[1], &v, NULL)) {
+		return false;
+	}
+	ace->flags = v;
+	
+	/* access mask */
+	if (strncmp(tok[2], "0x", 2) == 0) {
+		ace->access_mask = strtol(tok[2], NULL, 16);
+	} else {
+		if (!sddl_map_flags(ace_access_mask, tok[2], &v, NULL)) {
+			return false;
+		}
+		ace->access_mask = v;
+	}
+
+	/* object */
+	if (tok[3][0] != 0) {
+		NTSTATUS status = GUID_from_string(tok[3], 
+						   &ace->object.object.type.type);
+		if (!NT_STATUS_IS_OK(status)) {
+			return false;
+		}
+		ace->object.object.flags |= SEC_ACE_OBJECT_TYPE_PRESENT;
+	}
+
+	/* inherit object */
+	if (tok[4][0] != 0) {
+		NTSTATUS status = GUID_from_string(tok[4], 
+						   &ace->object.object.inherited_type.inherited_type);
+		if (!NT_STATUS_IS_OK(status)) {
+			return false;
+		}
+		ace->object.object.flags |= SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT;
+	}
+
+	/* trustee */
+	s = tok[5];
+	sid = sddl_decode_sid(mem_ctx, &s, domain_sid);
+	if (sid == NULL) {
+		return false;
+	}
+	ace->trustee = *sid;
+	talloc_free(sid);
+
+	return true;
+}
+
+static const struct flag_map acl_flags[] = {
+	{ "P", SEC_DESC_DACL_PROTECTED },
+	{ "AR", SEC_DESC_DACL_AUTO_INHERIT_REQ },
+	{ "AI", SEC_DESC_DACL_AUTO_INHERITED },
+	{ NULL, 0 }
+};
+
+/*
+  decode an ACL
+*/
+static struct security_acl *sddl_decode_acl(struct security_descriptor *sd, 
+					    const char **sddlp, uint32_t *flags,
+					    const struct dom_sid *domain_sid)
+{
+	const char *sddl = *sddlp;
+	struct security_acl *acl;
+	size_t len;
+
+	*flags = 0;
+
+	acl = talloc_zero(sd, struct security_acl);
+	if (acl == NULL) return NULL;
+	acl->revision = SECURITY_ACL_REVISION_NT4;
+
+	if (isupper(sddl[0]) && sddl[1] == ':') {
+		/* its an empty ACL */
+		return acl;
+	}
+
+	/* work out the ACL flags */
+	if (!sddl_map_flags(acl_flags, sddl, flags, &len)) {
+		talloc_free(acl);
+		return NULL;
+	}
+	sddl += len;
+
+	/* now the ACEs */
+	while (*sddl == '(') {
+		char *astr;
+		len = strcspn(sddl+1, ")");
+		astr = talloc_strndup(acl, sddl+1, len);
+		if (astr == NULL || sddl[len+1] != ')') {
+			talloc_free(acl);
+			return NULL;
+		}
+		acl->aces = talloc_realloc(acl, acl->aces, struct security_ace, 
+					   acl->num_aces+1);
+		if (acl->aces == NULL) {
+			talloc_free(acl);
+			return NULL;
+		}
+		if (!sddl_decode_ace(acl->aces, &acl->aces[acl->num_aces], 
+				     astr, domain_sid)) {
+			talloc_free(acl);
+			return NULL;
+		}
+		switch (acl->aces[acl->num_aces].type) {
+		case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
+		case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
+		case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
+		case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
+			acl->revision = SECURITY_ACL_REVISION_ADS;
+			break;
+		default:
+			break;
+		}
+		talloc_free(astr);
+		sddl += len+2;
+		acl->num_aces++;
+	}
+
+	(*sddlp) = sddl;
+	return acl;
+}
+
+/*
+  decode a security descriptor in SDDL format
+*/
+struct security_descriptor *sddl_decode(TALLOC_CTX *mem_ctx, const char *sddl,
+					const struct dom_sid *domain_sid)
+{
+	struct security_descriptor *sd;
+	sd = talloc_zero(mem_ctx, struct security_descriptor);
+
+	sd->revision = SECURITY_DESCRIPTOR_REVISION_1;
+	sd->type     = SEC_DESC_SELF_RELATIVE;
+	
+	while (*sddl) {
+		uint32_t flags;
+		char c = sddl[0];
+		if (sddl[1] != ':') goto failed;
+
+		sddl += 2;
+		switch (c) {
+		case 'D':
+			if (sd->dacl != NULL) goto failed;
+			sd->dacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
+			if (sd->dacl == NULL) goto failed;
+			sd->type |= flags | SEC_DESC_DACL_PRESENT;
+			break;
+		case 'S':
+			if (sd->sacl != NULL) goto failed;
+			sd->sacl = sddl_decode_acl(sd, &sddl, &flags, domain_sid);
+			if (sd->sacl == NULL) goto failed;
+			/* this relies on the SEC_DESC_SACL_* flags being
+			   1 bit shifted from the SEC_DESC_DACL_* flags */
+			sd->type |= (flags<<1) | SEC_DESC_SACL_PRESENT;
+			break;
+		case 'O':
+			if (sd->owner_sid != NULL) goto failed;
+			sd->owner_sid = sddl_decode_sid(sd, &sddl, domain_sid);
+			if (sd->owner_sid == NULL) goto failed;
+			break;
+		case 'G':
+			if (sd->group_sid != NULL) goto failed;
+			sd->group_sid = sddl_decode_sid(sd, &sddl, domain_sid);
+			if (sd->group_sid == NULL) goto failed;
+			break;
+		}
+	}
+
+	return sd;
+
+failed:
+	DEBUG(2,("Badly formatted SDDL '%s'\n", sddl));
+	talloc_free(sd);
+	return NULL;
+}
+
+/*
+  turn a set of flags into a string
+*/
+static char *sddl_flags_to_string(TALLOC_CTX *mem_ctx, const struct flag_map *map,
+				  uint32_t flags, bool check_all)
+{
+	int i;
+	char *s;
+
+	/* try to find an exact match */
+	for (i=0;map[i].name;i++) {
+		if (map[i].flag == flags) {
+			return talloc_strdup(mem_ctx, map[i].name);
+		}
+	}
+
+	s = talloc_strdup(mem_ctx, "");
+
+	/* now by bits */
+	for (i=0;map[i].name;i++) {
+		if ((flags & map[i].flag) != 0) {
+			s = talloc_asprintf_append_buffer(s, "%s", map[i].name);
+			if (s == NULL) goto failed;
+			flags &= ~map[i].flag;
+		}
+	}
+
+	if (check_all && flags != 0) {
+		goto failed;
+	}
+
+	return s;
+
+failed:
+	talloc_free(s);
+	return NULL;
+}
+
+/*
+  encode a sid in SDDL format
+*/
+static char *sddl_encode_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
+			     const struct dom_sid *domain_sid)
+{
+	int i;
+	char *sidstr;
+
+	sidstr = dom_sid_string(mem_ctx, sid);
+	if (sidstr == NULL) return NULL;
+
+	/* seen if its a well known sid */ 
+	for (i=0;sid_codes[i].sid;i++) {
+		if (strcmp(sidstr, sid_codes[i].sid) == 0) {
+			talloc_free(sidstr);
+			return talloc_strdup(mem_ctx, sid_codes[i].code);
+		}
+	}
+
+	/* or a well known rid in our domain */
+	if (dom_sid_in_domain(domain_sid, sid)) {
+		uint32_t rid = sid->sub_auths[sid->num_auths-1];
+		for (;i<ARRAY_SIZE(sid_codes);i++) {
+			if (rid == sid_codes[i].rid) {
+				talloc_free(sidstr);
+				return talloc_strdup(mem_ctx, sid_codes[i].code);
+			}
+		}
+	}
+	
+	talloc_free(sidstr);
+
+	/* TODO: encode well known sids as two letter codes */
+	return dom_sid_string(mem_ctx, sid);
+}
+
+
+/*
+  encode an ACE in SDDL format
+*/
+static char *sddl_encode_ace(TALLOC_CTX *mem_ctx, const struct security_ace *ace,
+			     const struct dom_sid *domain_sid)
+{
+	char *sddl = NULL;
+	TALLOC_CTX *tmp_ctx;
+	const char *s_type="", *s_flags="", *s_mask="", 
+		*s_object="", *s_iobject="", *s_trustee="";
+
+	tmp_ctx = talloc_new(mem_ctx);
+	if (tmp_ctx == NULL) {
+		DEBUG(0, ("talloc_new failed\n"));
+		return NULL;
+	}
+
+	s_type = sddl_flags_to_string(tmp_ctx, ace_types, ace->type, true);
+	if (s_type == NULL) goto failed;
+
+	s_flags = sddl_flags_to_string(tmp_ctx, ace_flags, ace->flags, true);
+	if (s_flags == NULL) goto failed;
+


-- 
SAMBA-CTDB repository


More information about the samba-cvs mailing list