svn commit: samba r7567 - in branches/SAMBA_4_0/source/libcli/ldap: .

tridge at samba.org tridge at samba.org
Tue Jun 14 03:53:35 GMT 2005


Author: tridge
Date: 2005-06-14 03:53:35 +0000 (Tue, 14 Jun 2005)
New Revision: 7567

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

Log:
added wire parsing of NOT and extended ldap search requests. This
allows us to parse and handle the complex queries we are getting from
w2k, such as

(|(|(&(!(groupType:1.2.840.113556.1.4.803=1))(groupType:1.2.840.113556.1.4.803=2147483648)(groupType:1.2.840.113556.1.4.804=6))(samAccountType=805306368))(samAccountType=805306369))

Modified:
   branches/SAMBA_4_0/source/libcli/ldap/ldap.c


Changeset:
Modified: branches/SAMBA_4_0/source/libcli/ldap/ldap.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/ldap/ldap.c	2005-06-14 03:52:27 UTC (rev 7566)
+++ branches/SAMBA_4_0/source/libcli/ldap/ldap.c	2005-06-14 03:53:35 UTC (rev 7567)
@@ -31,8 +31,10 @@
 
 static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree)
 {
+	int i;
+
 	switch (tree->operation) {
-	case LDB_OP_SIMPLE: {
+	case LDB_OP_SIMPLE:
 		if ((tree->u.simple.value.length == 1) &&
 		    (((char *)(tree->u.simple.value.data))[0] == '*')) {
 			/* Just a presence test */
@@ -43,7 +45,7 @@
 			return !data->has_error;
 		}
 
-		/* Equality is all we currently do... */
+		/* equality test */
 		asn1_push_tag(data, 0xa3);
 		asn1_write_OctetString(data, tree->u.simple.attr,
 				      strlen(tree->u.simple.attr));
@@ -51,29 +53,51 @@
 				      tree->u.simple.value.length);
 		asn1_pop_tag(data);
 		break;
-	}
 
-	case LDB_OP_AND: {
-		int i;
-
-		asn1_push_tag(data, 0xa0);
-		for (i=0; i<tree->u.list.num_elements; i++) {
-			ldap_push_filter(data, tree->u.list.elements[i]);
+	case LDB_OP_EXTENDED:
+		/*
+		  MatchingRuleAssertion ::= SEQUENCE {
+		  matchingRule    [1] MatchingRuleID OPTIONAL,
+		  type            [2] AttributeDescription OPTIONAL,
+		  matchValue      [3] AssertionValue,
+		  dnAttributes    [4] BOOLEAN DEFAULT FALSE
+		  }
+		*/
+		asn1_push_tag(data, 0xa9);
+		if (tree->u.extended.rule_id) {
+			asn1_push_tag(data, 1);
+			asn1_write_OctetString(data, tree->u.extended.rule_id,
+					       strlen(tree->u.extended.rule_id));
+			asn1_pop_tag(data);
 		}
+		if (tree->u.extended.attr) {
+			asn1_push_tag(data, 2);
+			asn1_write_OctetString(data, tree->u.extended.attr,
+					       strlen(tree->u.extended.attr));
+			asn1_pop_tag(data);
+		}
+		asn1_push_tag(data, 3);
+		asn1_write_OctetString(data, tree->u.extended.value.data,
+				      tree->u.extended.value.length);
 		asn1_pop_tag(data);
+		if (tree->u.extended.dnAttributes) {
+			asn1_push_tag(data, 4);
+			asn1_write_BOOLEAN(data, True);
+			asn1_pop_tag(data);
+		}
+		asn1_pop_tag(data);
 		break;
-	}
+		
 
-	case LDB_OP_OR: {
-		int i;
-
-		asn1_push_tag(data, 0xa1);
+	case LDB_OP_AND:
+	case LDB_OP_OR:
+		asn1_push_tag(data, 0xa0 | (tree->operation==LDB_OP_AND?0:1));
 		for (i=0; i<tree->u.list.num_elements; i++) {
 			ldap_push_filter(data, tree->u.list.elements[i]);
 		}
 		asn1_pop_tag(data);
 		break;
-	}
+
 	default:
 		return False;
 	}
@@ -464,25 +488,34 @@
 		}
 		break;
 
+	case 2:
+		/* 'not' operation */
+		if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
+			goto failed;
+		}
+
+		ret->operation = LDB_OP_NOT;
+		ret->u.not.child = ldap_decode_filter_tree(ret, data);
+
+		if (!asn1_end_tag(data)) {
+			goto failed;
+		}
+		break;
+
 	case 3: {
 		/* equalityMatch */
 		const char *attrib;
 		DATA_BLOB value;
 
-		ret->operation = LDB_OP_SIMPLE;
-
-		if (tag_desc != 0xa0) {
-			/* context compound */
-			goto failed;
-		}
-
-		asn1_start_tag(data, ASN1_CONTEXT(3));
+		asn1_start_tag(data, ASN1_CONTEXT(filter_tag));
 		asn1_read_OctetString_talloc(mem_ctx, data, &attrib);
 		asn1_read_OctetString(data, &value);
 		asn1_end_tag(data);
 		if ((data->has_error) || (attrib == NULL) || (value.data == NULL)) {
 			goto failed;
 		}
+
+		ret->operation = LDB_OP_SIMPLE;
 		ret->u.simple.attr = talloc_steal(ret, attrib);
 		ret->u.simple.value.data = talloc_steal(ret, value.data);
 		ret->u.simple.value.length = value.length;
@@ -490,37 +523,64 @@
 	}
 	case 7: {
 		/* Normal presence, "attribute=*" */
-		int attr_len;
-		if (tag_desc != 0x80) {
-			/* context simple */
+		char *attr;
+
+		if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(filter_tag))) {
 			goto failed;
 		}
-		if (!asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(7))) {
+		if (!asn1_read_LDAPString(data, &attr)) {
 			goto failed;
 		}
 
 		ret->operation = LDB_OP_SIMPLE;
-
-		attr_len = asn1_tag_remaining(data);
-
-		ret->u.simple.attr = talloc_size(ret, attr_len+1);
-		if (ret->u.simple.attr == NULL) {
+		ret->u.simple.attr = talloc_steal(ret, attr);
+		ret->u.simple.value.data = talloc_strdup(ret, "*");
+		if (ret->u.simple.value.data == NULL) {
 			goto failed;
 		}
-		if (!asn1_read(data, ret->u.simple.attr, attr_len)) {
+		ret->u.simple.value.length = 1;
+		if (!asn1_end_tag(data)) {
 			goto failed;
 		}
-		ret->u.simple.attr[attr_len] = 0;
-		ret->u.simple.value.data = talloc_strdup(ret, "*");
-		if (ret->u.simple.value.data == NULL) {
+		break;
+	}
+	case 9: {
+		char *oid, *attr, *value;
+		uint8_t dnAttributes;
+		/* an extended search */
+		if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
 			goto failed;
 		}
-		ret->u.simple.value.length = 1;
+
+		asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1));
+		asn1_read_LDAPString(data, &oid);
+		asn1_end_tag(data);
+		asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(2));
+		asn1_read_LDAPString(data, &attr);
+		asn1_end_tag(data);
+		asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(3));
+		asn1_read_LDAPString(data, &value);
+		asn1_end_tag(data);
+		asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4));
+		asn1_read_uint8(data, &dnAttributes);
+		asn1_end_tag(data);
+		if ((data->has_error) || (oid == NULL) || (value == NULL)) {
+			goto failed;
+		}
+
+		ret->operation               = LDB_OP_EXTENDED;
+		ret->u.extended.attr         = talloc_steal(ret, attr);
+		ret->u.extended.rule_id      = talloc_steal(ret, oid);
+		ret->u.extended.value.data   = talloc_steal(ret, value);
+		ret->u.extended.value.length = strlen(value);
+		ret->u.extended.dnAttributes = dnAttributes;
+
 		if (!asn1_end_tag(data)) {
 			goto failed;
 		}
 		break;
 	}
+
 	default:
 		DEBUG(0,("Unsupported LDAP filter operation 0x%x\n", filter_tag));
 		goto failed;



More information about the samba-cvs mailing list