summaryrefslogtreecommitdiff
path: root/source4/libcli
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2005-08-02 14:04:22 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:30:57 -0500
commitf297f82398d77e5d2fe5faf5de8b581ad5a6acd1 (patch)
tree05ef98c6a2335fc806b71434f2987d093700c7fa /source4/libcli
parente3374bb48daa0235811d384bce55e39b6cf6abda (diff)
downloadsamba-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)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/ldap/ldap.c66
1 files changed, 49 insertions, 17 deletions
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;
}