Author: idra
Date: 2005-08-02 14:04:22 +0000 (Tue, 02 Aug 2005)
New Revision: 8917

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

Log:

  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


Modified:
   branches/SAMBA_4_0/source/lib/ldb/common/ldb_match.c
   branches/SAMBA_4_0/source/libcli/ldap/ldap.c


Changeset:
Modified: branches/SAMBA_4_0/source/lib/ldb/common/ldb_match.c
===================================================================
--- branches/SAMBA_4_0/source/lib/ldb/common/ldb_match.c        2005-08-02 
07:26:29 UTC (rev 8916)
+++ branches/SAMBA_4_0/source/lib/ldb/common/ldb_match.c        2005-08-02 
14:04:22 UTC (rev 8917)
@@ -187,6 +187,8 @@
                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;

Modified: branches/SAMBA_4_0/source/libcli/ldap/ldap.c
===================================================================
--- branches/SAMBA_4_0/source/libcli/ldap/ldap.c        2005-08-02 07:26:29 UTC 
(rev 8916)
+++ branches/SAMBA_4_0/source/libcli/ldap/ldap.c        2005-08-02 14:04:22 UTC 
(rev 8917)
@@ -787,36 +787,68 @@
                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;
                }

Reply via email to