diff options
author | Simo Sorce <idra@samba.org> | 2005-08-02 14:04:22 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:30:57 -0500 |
commit | f297f82398d77e5d2fe5faf5de8b581ad5a6acd1 (patch) | |
tree | 05ef98c6a2335fc806b71434f2987d093700c7fa | |
parent | e3374bb48daa0235811d384bce55e39b6cf6abda (diff) | |
download | samba-f297f82398d77e5d2fe5faf5de8b581ad5a6acd1.tar.gz samba-f297f82398d77e5d2fe5faf5de8b581ad5a6acd1.tar.bz2 samba-f297f82398d77e5d2fe5faf5de8b581ad5a6acd1.zip |
r8917: Better support for extended ldap search operations
Try to follow the RFC where possible and adapt to
openLdap and AD way of handling this structure
(This used to be commit d844d45d87b4114bc1b9af2e40f8c27ba3e219de)
-rw-r--r-- | source4/lib/ldb/common/ldb_match.c | 2 | ||||
-rw-r--r-- | source4/libcli/ldap/ldap.c | 66 |
2 files changed, 51 insertions, 17 deletions
diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c index 97e0a60ace..7ff84f70c3 100644 --- a/source4/lib/ldb/common/ldb_match.c +++ b/source4/lib/ldb/common/ldb_match.c @@ -187,6 +187,8 @@ static int ldb_match_equality(struct ldb_context *ldb, return 0; } + /* TODO: handle the "*" case derived from an extended search + operation without the attibute type defined */ el = ldb_msg_find_element(msg, tree->u.equality.attr); if (el == NULL) { return 0; diff --git a/source4/libcli/ldap/ldap.c b/source4/libcli/ldap/ldap.c index b71c4a6dff..f7f6feea38 100644 --- a/source4/libcli/ldap/ldap.c +++ b/source4/libcli/ldap/ldap.c @@ -787,36 +787,68 @@ static struct ldb_parse_tree *ldap_decode_filter_tree(TALLOC_CTX *mem_ctx, break; } case 9: { - char *oid, *attr, *value; + char *oid = NULL, *attr = NULL, *value; uint8_t dnAttributes; /* an extended search */ if (!asn1_start_tag(data, ASN1_CONTEXT(filter_tag))) { goto failed; } - 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); + /* FIXME: read carefully rfc2251.txt there are a number of 'MUST's + we need to check we properly implement --SSS */ + /* either oid or type must be defined */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(1))) { /* optional */ + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(1)); + asn1_read_LDAPString(data, &oid); + asn1_end_tag(data); + } + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(2))) { /* optional */ + 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)) { + /* dnAttributes is marked as BOOLEAN DEFAULT FALSE + it is not marked as OPTIONAL but openldap tools + do not set this unless it is to be set as TRUE + NOTE: openldap tools do not work with AD as it + seems that AD always requires the dnAttributes + boolean value to be set */ + if (asn1_peek_tag(data, ASN1_CONTEXT_SIMPLE(4))) { + asn1_start_tag(data, ASN1_CONTEXT_SIMPLE(4)); + asn1_read_uint8(data, &dnAttributes); + asn1_end_tag(data); + } else { + dnAttributes = 0; + } + if ((oid == NULL && attr == 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 (oid) { + ret->operation = LDB_OP_EXTENDED; + /* From the RFC2251: If the type field is + absent and matchingRule is present, the matchValue is compared + against all attributes in an entry which support that matchingRule + */ + if (attr) { + ret->u.extended.attr = talloc_steal(ret, attr); + } else { + ret->u.extended.attr = talloc_strdup(ret, "*"); + } + 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; + } else { + ret->operation = LDB_OP_EQUALITY; + ret->u.equality.attr = talloc_steal(ret, attr); + ret->u.equality.value.data = talloc_steal(ret, value); + ret->u.equality.value.length = strlen(value); + } if (!asn1_end_tag(data)) { goto failed; } |