summaryrefslogtreecommitdiff
path: root/source4/libcli/ldap
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-06-14 03:53:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:18:10 -0500
commit6426f2a39ab42e164e29265b6d04cec9dca92eca (patch)
tree8eed5634203c891b787ec6f27c80da0bd2f7fcd9 /source4/libcli/ldap
parent9d6b3e62c2dd27c7e8f72d6887888f686d868981 (diff)
downloadsamba-6426f2a39ab42e164e29265b6d04cec9dca92eca.tar.gz
samba-6426f2a39ab42e164e29265b6d04cec9dca92eca.tar.bz2
samba-6426f2a39ab42e164e29265b6d04cec9dca92eca.zip
r7567: 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)) (This used to be commit 041bce591306a0fb26bd31fe371e30021ea5c0c1)
Diffstat (limited to 'source4/libcli/ldap')
-rw-r--r--source4/libcli/ldap/ldap.c134
1 files changed, 97 insertions, 37 deletions
diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c
index 0d310b4eed..048a60317a 100644
--- a/source4/libcli/ldap/ldap.c
+++ b/source4/libcli/ldap/ldap.c
@@ -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 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
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 @@ static BOOL ldap_push_filter(struct asn1_data *data, struct ldb_parse_tree *tree
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 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
}
break;
- case 3: {
- /* equalityMatch */
- const char *attrib;
- DATA_BLOB value;
+ case 2:
+ /* 'not' operation */
+ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) {
+ goto failed;
+ }
- ret->operation = LDB_OP_SIMPLE;
+ ret->operation = LDB_OP_NOT;
+ ret->u.not.child = ldap_decode_filter_tree(ret, data);
- if (tag_desc != 0xa0) {
- /* context compound */
+ if (!asn1_end_tag(data)) {
goto failed;
}
+ break;
- asn1_start_tag(data, ASN1_CONTEXT(3));
+ case 3: {
+ /* equalityMatch */
+ const char *attrib;
+ DATA_BLOB value;
+
+ 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 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx,
}
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;