svn commit: samba r12137 - in branches/SAMBA_4_0/source: libcli/security torture/local

tridge at samba.org tridge at samba.org
Fri Dec 9 04:54:31 GMT 2005


Author: tridge
Date: 2005-12-09 04:54:30 +0000 (Fri, 09 Dec 2005)
New Revision: 12137

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12137

Log:

added sddl_encode(), the reverse of the sddl_decode() function added a
couple of days ago. Doesn't yet encode using the shorthand for well
known SIDs.


Modified:
   branches/SAMBA_4_0/source/libcli/security/sddl.c
   branches/SAMBA_4_0/source/torture/local/sddl.c


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/security/sddl.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/security/sddl.c	2005-12-09 04:11:44 UTC (rev 12136)
+++ branches/SAMBA_4_0/source/libcli/security/sddl.c	2005-12-09 04:54:30 UTC (rev 12137)
@@ -263,6 +263,8 @@
 	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;
@@ -361,3 +363,171 @@
 	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(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,
+			     struct dom_sid *domain_sid)
+{
+	/* 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,
+			     struct dom_sid *domain_sid)
+{
+	char *sddl;
+	TALLOC_CTX *tmp_ctx;
+	const char *s_type="", *s_flags="", *s_mask="", 
+		*s_object="", *s_iobject="", *s_trustee="";
+
+	tmp_ctx = talloc_new(mem_ctx);
+
+	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;
+
+	s_mask = sddl_flags_to_string(tmp_ctx, ace_access_mask, ace->access_mask, True);
+	if (s_mask == NULL) goto failed;
+
+	s_object = GUID_string(tmp_ctx, &ace->object.object.type.type);
+
+	s_iobject = GUID_string(tmp_ctx, &ace->object.object.inherited_type.inherited_type);
+	
+	s_trustee = sddl_encode_sid(tmp_ctx, &ace->trustee, domain_sid);
+
+	sddl = talloc_asprintf(mem_ctx, "%s;%s;%s;%s;%s;%s",
+			       s_type, s_flags, s_mask, s_object, s_iobject, s_trustee);
+
+failed:
+	talloc_free(tmp_ctx);
+	return sddl;
+}
+
+/*
+  encode an ACL in SDDL format
+*/
+static char *sddl_encode_acl(TALLOC_CTX *mem_ctx, const struct security_acl *acl,
+			     uint32_t flags, struct dom_sid *domain_sid)
+{
+	char *sddl;
+	int i;
+
+	/* add any ACL flags */
+	sddl = sddl_flags_to_string(mem_ctx, acl_flags, flags, False);
+	if (sddl == NULL) goto failed;
+
+	/* now the ACEs, encoded in braces */
+	for (i=0;i<acl->num_aces;i++) {
+		char *ace = sddl_encode_ace(sddl, &acl->aces[i], domain_sid);
+		if (ace == NULL) goto failed;
+		sddl = talloc_asprintf_append(sddl, "(%s)", ace);
+		if (sddl == NULL) goto failed;
+		talloc_free(ace);
+	}
+
+	return sddl;
+
+failed:
+	talloc_free(sddl);
+	return NULL;
+}
+
+
+/*
+  encode a security descriptor to SDDL format
+*/
+char *sddl_encode(TALLOC_CTX *mem_ctx, const struct security_descriptor *sd,
+		  struct dom_sid *domain_sid)
+{
+	char *sddl;
+	TALLOC_CTX *tmp_ctx;
+
+	/* start with a blank string */
+	sddl = talloc_strdup(mem_ctx, "");
+	if (sddl == NULL) goto failed;
+
+	tmp_ctx = talloc_new(mem_ctx);
+
+	if (sd->owner_sid != NULL) {
+		char *sid = sddl_encode_sid(tmp_ctx, sd->owner_sid, domain_sid);
+		if (sid == NULL) goto failed;
+		sddl = talloc_asprintf_append(sddl, "O:%s", sid);
+		if (sddl == NULL) goto failed;
+	}
+
+	if (sd->group_sid != NULL) {
+		char *sid = sddl_encode_sid(tmp_ctx, sd->group_sid, domain_sid);
+		if (sid == NULL) goto failed;
+		sddl = talloc_asprintf_append(sddl, "G:%s", sid);
+		if (sddl == NULL) goto failed;
+	}
+
+	if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl != NULL) {
+		char *acl = sddl_encode_acl(tmp_ctx, sd->dacl, sd->type, domain_sid);
+		if (acl == NULL) goto failed;
+		sddl = talloc_asprintf_append(sddl, "D:%s", acl);
+		if (sddl == NULL) goto failed;
+	}
+
+	if ((sd->type & SEC_DESC_SACL_PRESENT) && sd->sacl != NULL) {
+		char *acl = sddl_encode_acl(tmp_ctx, sd->sacl, sd->type>>1, domain_sid);
+		if (acl == NULL) goto failed;
+		sddl = talloc_asprintf_append(sddl, "S:%s", acl);
+		if (sddl == NULL) goto failed;
+	}
+
+	talloc_free(tmp_ctx);
+	return sddl;
+
+failed:
+	talloc_free(sddl);
+	return NULL;
+}
+
+

Modified: branches/SAMBA_4_0/source/torture/local/sddl.c
===================================================================
--- branches/SAMBA_4_0/source/torture/local/sddl.c	2005-12-09 04:11:44 UTC (rev 12136)
+++ branches/SAMBA_4_0/source/torture/local/sddl.c	2005-12-09 04:54:30 UTC (rev 12137)
@@ -29,14 +29,34 @@
 */
 static BOOL test_sddl(TALLOC_CTX *mem_ctx, const char *sddl)
 {
-	struct security_descriptor *sd;
+	struct security_descriptor *sd, *sd2;
 	struct dom_sid *domain;
+	const char *sddl2;
+
 	domain = dom_sid_parse_talloc(mem_ctx, "S-1-2-3-4");
 	sd = sddl_decode(mem_ctx, sddl, domain);
 	if (sd == NULL) {
 		printf("Failed to decode '%s'\n", sddl);
 		return False;
 	}
+
+	sddl2 = sddl_encode(mem_ctx, sd, domain);
+	if (sddl2 == NULL) {
+		printf("Failed to re-encode '%s'\n", sddl);
+		return False;
+	}
+
+	sd2 = sddl_decode(mem_ctx, sddl2, domain);
+	if (sd2 == NULL) {
+		printf("Failed to decode2 '%s'\n", sddl2);
+		return False;
+	}
+
+	if (!security_descriptor_equal(sd, sd2)) {
+		printf("Failed equality test for '%s'\n", sddl);
+		return False;
+	}
+
 	if (DEBUGLVL(2)) {
 		NDR_PRINT_DEBUG(security_descriptor, sd);
 	}



More information about the samba-cvs mailing list