]> git.sur5r.net Git - openldap/commitdiff
Referrals and misc other changes
authorKurt Zeilenga <kurt@openldap.org>
Thu, 10 Oct 2002 03:24:50 +0000 (03:24 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Thu, 10 Oct 2002 03:24:50 +0000 (03:24 +0000)
libraries/libldap/controls.c
libraries/libldap/dnssrv.c
libraries/libldap/error.c
libraries/libldap/getvalues.c
libraries/libldap/ldap-int.h
libraries/libldap/options.c
libraries/libldap/schema.c
libraries/libldap/unbind.c

index f3af141e1ea29c73ce025ceb104139fb37d23a78..3d9f3a5ac5606fcad6b7419e40649eb2677d012c 100644 (file)
@@ -187,33 +187,27 @@ int ldap_int_get_controls(
 
                tag = ber_scanf( ber, "{a" /*}*/, &tctrl->ldctl_oid );
 
-               if( tag != LBER_ERROR ) {
-                       tag = ber_peek_tag( ber, &len );
+               if( tag == LBER_ERROR ) {
+                       *ctrls = NULL;
+                       ldap_controls_free( tctrls );
+                       return LDAP_DECODING_ERROR;
                }
 
+               tag = ber_peek_tag( ber, &len );
+
                if( tag == LBER_BOOLEAN ) {
                        ber_int_t crit;
                        tag = ber_scanf( ber, "b", &crit );
                        tctrl->ldctl_iscritical = crit ? (char) 0 : (char) ~0;
-               }
-
-               if( tag != LBER_ERROR ) {
                        tag = ber_peek_tag( ber, &len );
                }
 
                if( tag == LBER_OCTETSTRING ) {
                        tag = ber_scanf( ber, "o", &tctrl->ldctl_value );
-
                } else {
                        tctrl->ldctl_value.bv_val = NULL;
                }
 
-               if( tag == LBER_ERROR ) {
-                       *ctrls = NULL;
-                       ldap_controls_free( tctrls );
-                       return LDAP_DECODING_ERROR;
-               }
-
                *ctrls = tctrls;
        }
                
index 72835f22e89bfec97fe73e8183aabc3778061195..ef5eb89d3b8f58806d0cac45cb66430b2939e97d 100644 (file)
@@ -121,46 +121,49 @@ int ldap_domain2dn(
        LDAP_CONST char *domain_in,
        char **dnp)
 {
-    char *domain, *s, *tok_r, *dn;
-    size_t loc;
+       char *domain, *s, *tok_r, *dn, *dntmp;
+       size_t loc;
 
        assert( domain_in != NULL );
        assert( dnp != NULL );
 
-    domain = LDAP_STRDUP(domain_in);
-    if (domain == NULL) {
+       domain = LDAP_STRDUP(domain_in);
+       if (domain == NULL) {
                return LDAP_NO_MEMORY;
-    }
-    dn = NULL;
-    loc = 0;
-
-    for (s = ldap_pvt_strtok(domain, ".", &tok_r);
-        s != NULL;
-        s = ldap_pvt_strtok(NULL, ".", &tok_r)) {
-       size_t len = strlen(s);
-
-       dn = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len );
-       if (dn == NULL) {
-           LDAP_FREE(domain);
-           return LDAP_NO_MEMORY;
-       }
-       if (loc > 0) {
-           /* not first time. */
-           strcpy(dn + loc, ",");
-           loc++;
        }
-       strcpy(dn + loc, "dc=");
-       loc += sizeof("dc=")-1;
+       dn = NULL;
+       loc = 0;
+
+       for (s = ldap_pvt_strtok(domain, ".", &tok_r);
+               s != NULL;
+               s = ldap_pvt_strtok(NULL, ".", &tok_r))
+       {
+               size_t len = strlen(s);
+
+               dntmp = (char *) LDAP_REALLOC(dn, loc + sizeof(",dc=") + len );
+               if (dn == NULL) {
+                       LDAP_FREE(dn);
+                   LDAP_FREE(domain);
+                   return LDAP_NO_MEMORY;
+               }
 
-       strcpy(dn + loc, s);
-       loc += len;
-    }
+               dn = dntmp;
 
-    LDAP_FREE(domain);
+               if (loc > 0) {
+                   /* not first time. */
+                   strcpy(dn + loc, ",");
+                   loc++;
+               }
+               strcpy(dn + loc, "dc=");
+               loc += sizeof("dc=")-1;
 
-    *dnp = dn;
+               strcpy(dn + loc, s);
+               loc += len;
+    }
 
-    return LDAP_SUCCESS;
+       LDAP_FREE(domain);
+       *dnp = dn;
+       return LDAP_SUCCESS;
 }
 
 /*
index 45f9eec86e4a8542766b7064a11d6c324ea5ce90..7aa9d4666701341d7585a3e20467c186e77a9751 100644 (file)
@@ -161,6 +161,7 @@ ldap_err2string( int err )
 void
 ldap_perror( LDAP *ld, LDAP_CONST char *str )
 {
+    int i;
        const struct ldaperror *e;
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ENTRY, "ldap_perror\n", 0,0,0 );
@@ -187,6 +188,13 @@ ldap_perror( LDAP *ld, LDAP_CONST char *str )
                fprintf( stderr, "\tadditional info: %s\n", ld->ld_error );
        }
 
+       if ( ld->ld_referrals != NULL && ld->ld_referrals[0] != NULL) {
+               fprintf( stderr, "\treferrals:\n" );
+               for (i=0; ld->ld_referrals[i]; i++) {
+                       fprintf( stderr, "\t\t%s\n", ld->ld_referrals[i] );
+               }
+       }
+
        fflush( stderr );
 }
 
@@ -282,6 +290,10 @@ ldap_parse_result(
                LDAP_FREE( ld->ld_matched );
                ld->ld_matched = NULL;
        }
+       if ( ld->ld_referrals ) {
+               LDAP_VFREE( ld->ld_referrals );
+               ld->ld_referrals = NULL;
+       }
 
        /* parse results */
 
@@ -298,13 +310,7 @@ ldap_parse_result(
                if( tag != LBER_ERROR ) {
                        /* peek for referrals */
                        if( ber_peek_tag(ber, &len) == LDAP_TAG_REFERRAL ) {
-                               if( referralsp != NULL ) {
-                                       tag = ber_scanf( ber, "v", referralsp );
-
-                               } else {
-                                       /* no place to put them so skip 'em */
-                                       tag = ber_scanf( ber, "x" );
-                               }
+                               tag = ber_scanf( ber, "v", &ld->ld_referrals );
                        }
                }
 
@@ -366,6 +372,10 @@ ldap_parse_result(
                        *errmsgp = LDAP_STRDUP( ld->ld_error );
                }
 
+               if( referralsp != NULL) {
+                       *referralsp = ldap_value_dup( ld->ld_referrals );
+               }
+
                /* Find the next result... */
                for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
                        /* skip over entries and references */
index 34ee28da563a40a9706cf1aca713aaea49f2dd3d..43e159f1903818d61e64e1ff964ca461b6405947 100644 (file)
@@ -175,3 +175,39 @@ ldap_value_free_len( struct berval **vals )
 {
        ber_bvecfree( vals );
 }
+
+char **
+ldap_value_dup( char *const *vals )
+{
+       char **new;
+       int i;
+
+       if( vals == NULL ) {
+               return NULL;
+       }
+
+       for( i=0; vals[i]; i++ ) {
+               ;   /* Count the number of values */
+       }
+
+       if( i == 0 ) {
+               return NULL;
+       }
+
+       new = LDAP_MALLOC( (i+1)*sizeof(char *) );  /* Alloc array of pointers */
+       if( new == NULL ) {
+               return NULL;
+       }
+
+       for( i=0; vals[i]; i++ ) {
+               new[i] = LDAP_STRDUP( vals[i] );   /* Dup each value */
+               if( new[i] == NULL ) {
+                       LDAP_VFREE( new );
+                       return NULL;
+               }
+       }
+       new[i] = NULL;
+
+       return new;
+}
+
index 01fe78bac11cae779cf74593372d9fef0b986b4e..b0c2bd93614cfe0bdbe4c161d74212f5a16be2c6 100644 (file)
@@ -295,6 +295,7 @@ struct ldap {
        ber_int_t       ld_errno;
        char    *ld_error;
        char    *ld_matched;
+       char    **ld_referrals;
        ber_len_t               ld_msgid;
 
        /* do not mess with these */
@@ -574,6 +575,12 @@ LDAP_F (int) ldap_int_tls_config LDAP_P(( LDAP *ld,
 LDAP_F (int) ldap_int_tls_start LDAP_P(( LDAP *ld,
        LDAPConn *conn, LDAPURLDesc *srv ));
 
+/*
+ *     in getvalues.c
+ */
+LDAP_F (char **) ldap_value_dup LDAP_P((
+       char *const *vals ));
+
 LDAP_END_DECL
 
 #endif /* _LDAP_INT_H */
index 45ceae125f6e12c7cb2546da522ad39d53be056a..45ec0e5f75e2480a9aa086a63b685c9676ed8ffa 100644 (file)
@@ -250,6 +250,20 @@ ldap_get_option(
 
                return LDAP_OPT_SUCCESS;
 
+       case LDAP_OPT_REFERRAL_URLS:
+               if(ld == NULL) {
+                       /* bad param */
+                       break;
+               } 
+
+               if( ld->ld_referrals == NULL ) {
+                       * (char ***) outvalue = NULL;
+               } else {
+                       * (char ***) outvalue = ldap_value_dup(ld->ld_referrals);
+               }
+
+               return LDAP_OPT_SUCCESS;
+
        case LDAP_OPT_API_FEATURE_INFO: {
                        LDAPAPIFeatureInfo *info = (LDAPAPIFeatureInfo *) outvalue;
                        int i;
@@ -316,8 +330,9 @@ ldap_set_option(
         * problem. Thus, we introduce a fix here.
         */
 
-       if (option == LDAP_OPT_DEBUG_LEVEL)
-           dbglvl = (int *) invalue;
+       if (option == LDAP_OPT_DEBUG_LEVEL) {
+               dbglvl = (int *) invalue;
+       }
 
        if( lo->ldo_valid != LDAP_INITIALIZED ) {
                ldap_int_initialize(lo, dbglvl);
@@ -573,6 +588,21 @@ ldap_set_option(
                        ld->ld_matched = LDAP_STRDUP(err);
                } return LDAP_OPT_SUCCESS;
 
+       case LDAP_OPT_REFERRAL_URLS: {
+                       char *const *referrals = (char *const *) invalue;
+                       
+                       if(ld == NULL) {
+                               /* need a struct ldap */
+                               break;
+                       }
+
+                       if( ld->ld_referrals ) {
+                               LDAP_VFREE(ld->ld_referrals);
+                       }
+
+                       ld->ld_referrals = ldap_value_dup(referrals);
+               } return LDAP_OPT_SUCCESS;
+
        case LDAP_OPT_API_FEATURE_INFO:
                /* read-only */
                break;
@@ -584,7 +614,7 @@ ldap_set_option(
        default:
 #ifdef HAVE_TLS
                if ( ldap_pvt_tls_set_option( ld, option, (void *)invalue ) == 0 )
-               return LDAP_OPT_SUCCESS;
+                       return LDAP_OPT_SUCCESS;
 #endif
 #ifdef HAVE_CYRUS_SASL
                if ( ldap_int_sasl_set_option( ld, option, (void *)invalue ) == 0 )
index 93a1daf381a10ab12a2b8bf451abccc5e17a1507..417b4bdba6603b95d500c15f09823dd3e8f414ff 100644 (file)
@@ -56,6 +56,11 @@ ldap_objectclass2name( LDAPObjectClass * oc )
        return( choose_name( oc->oc_names, oc->oc_oid ) );
 }
 
+LDAP_CONST char *
+ldap_contentrule2name( LDAPContentRule * cr )
+{
+       return( choose_name( cr->cr_names, cr->cr_oid ) );
+}
 
 /*
  * When pretty printing the entities we will be appending to a buffer.
@@ -383,7 +388,7 @@ ldap_matchingrule2bv( LDAPMatchingRule * mr, struct berval *bv )
                print_qdstring(ss,mr->mr_desc);
        }
 
-       if ( mr->mr_obsolete == LDAP_SCHEMA_YES ) {
+       if ( mr->mr_obsolete ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -442,7 +447,7 @@ ldap_matchingruleuse2bv( LDAPMatchingRuleUse * mru, struct berval *bv )
                print_qdstring(ss,mru->mru_desc);
        }
 
-       if ( mru->mru_obsolete == LDAP_SCHEMA_YES ) {
+       if ( mru->mru_obsolete ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -501,7 +506,7 @@ ldap_objectclass2bv( LDAPObjectClass * oc, struct berval *bv )
                print_qdstring(ss,oc->oc_desc);
        }
 
-       if ( oc->oc_obsolete == LDAP_SCHEMA_YES ) {
+       if ( oc->oc_obsolete ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -555,6 +560,85 @@ ldap_objectclass2bv( LDAPObjectClass * oc, struct berval *bv )
        return(bv);
 }
 
+char *
+ldap_contentrule2str( LDAPContentRule * cr )
+{
+       struct berval bv;
+       if (ldap_contentrule2bv( cr, &bv ))
+               return(bv.bv_val);
+       else
+               return NULL;
+}
+
+struct berval *
+ldap_contentrule2bv( LDAPContentRule * cr, struct berval *bv )
+{
+       safe_string * ss;
+       
+       ss = new_safe_string(256);
+       if ( !ss )
+               return NULL;
+
+       print_literal(ss,"("/*)*/);
+       print_whsp(ss);
+
+       print_numericoid(ss, cr->cr_oid);
+       print_whsp(ss);
+
+       if ( cr->cr_names ) {
+               print_literal(ss,"NAME");
+               print_qdescrs(ss,cr->cr_names);
+       }
+
+       if ( cr->cr_desc ) {
+               print_literal(ss,"DESC");
+               print_qdstring(ss,cr->cr_desc);
+       }
+
+       if ( cr->cr_obsolete ) {
+               print_literal(ss, "OBSOLETE");
+               print_whsp(ss);
+       }
+
+       if ( cr->cr_oc_oids_aux ) {
+               print_literal(ss,"AUX");
+               print_whsp(ss);
+               print_oids(ss,cr->cr_oc_oids_aux);
+               print_whsp(ss);
+       }
+
+       if ( cr->cr_at_oids_must ) {
+               print_literal(ss,"MUST");
+               print_whsp(ss);
+               print_oids(ss,cr->cr_at_oids_must);
+               print_whsp(ss);
+       }
+
+       if ( cr->cr_at_oids_may ) {
+               print_literal(ss,"MAY");
+               print_whsp(ss);
+               print_oids(ss,cr->cr_at_oids_may);
+               print_whsp(ss);
+       }
+
+       if ( cr->cr_at_oids_not ) {
+               print_literal(ss,"NOT");
+               print_whsp(ss);
+               print_oids(ss,cr->cr_at_oids_not);
+               print_whsp(ss);
+       }
+
+       print_whsp(ss);
+       print_extensions(ss, cr->cr_extensions);
+
+       print_literal(ss, /*(*/")");
+
+       bv->bv_val = safe_strdup(ss);
+       bv->bv_len = ss->pos;
+       safe_string_free(ss);
+       return(bv);
+}
+
 char *
 ldap_attributetype2str( LDAPAttributeType * at )
 {
@@ -590,7 +674,7 @@ ldap_attributetype2bv(  LDAPAttributeType * at, struct berval *bv )
                print_qdstring(ss,at->at_desc);
        }
 
-       if ( at->at_obsolete == LDAP_SCHEMA_YES ) {
+       if ( at->at_obsolete ) {
                print_literal(ss, "OBSOLETE");
                print_whsp(ss);
        }
@@ -2124,6 +2208,7 @@ ldap_str2objectclass( LDAP_CONST char * s,
                                     !strcmp(sval, "STRUCTURAL") ||
                                     !strcmp(sval, "AUXILIARY") ||
                                     !strcmp(sval, "MUST") ||
+                                    !strcmp(sval, "MAY") ||
                                     !strncmp(sval, "X-", 2) ) {
                                        /* Missing OID, backtrack */
                                        ss = savepos;
@@ -2324,6 +2409,267 @@ ldap_str2objectclass( LDAP_CONST char * s,
        }
 }
 
+void
+ldap_contentrule_free(LDAPContentRule * cr)
+{
+       LDAP_FREE(cr->cr_oid);
+       if (cr->cr_names) LDAP_VFREE(cr->cr_names);
+       if (cr->cr_desc) LDAP_FREE(cr->cr_desc);
+       if (cr->cr_oc_oids_aux) LDAP_VFREE(cr->cr_oc_oids_aux);
+       if (cr->cr_at_oids_must) LDAP_VFREE(cr->cr_at_oids_must);
+       if (cr->cr_at_oids_may) LDAP_VFREE(cr->cr_at_oids_may);
+       if (cr->cr_at_oids_not) LDAP_VFREE(cr->cr_at_oids_not);
+       free_extensions(cr->cr_extensions);
+       LDAP_FREE(cr);
+}
+
+LDAPContentRule *
+ldap_str2contentrule( LDAP_CONST char * s,
+       int * code,
+       LDAP_CONST char ** errp,
+       LDAP_CONST int flags )
+{
+       int kind;
+       const char * ss = s;
+       char * sval;
+       int seen_name = 0;
+       int seen_desc = 0;
+       int seen_obsolete = 0;
+       int seen_aux = 0;
+       int seen_must = 0;
+       int seen_may = 0;
+       int seen_not = 0;
+       LDAPContentRule * cr;
+       char ** ext_vals;
+       const char * savepos;
+
+       if ( !s ) {
+               *code = LDAP_SCHERR_EMPTY;
+               *errp = "";
+               return NULL;
+       }
+
+       *errp = s;
+       cr = LDAP_CALLOC(1,sizeof(LDAPContentRule));
+
+       if ( !cr ) {
+               *code = LDAP_SCHERR_OUTOFMEM;
+               return NULL;
+       }
+
+       kind = get_token(&ss,&sval);
+       if ( kind != TK_LEFTPAREN ) {
+               *code = LDAP_SCHERR_NOLEFTPAREN;
+               LDAP_FREE(sval);
+               ldap_contentrule_free(cr);
+               return NULL;
+       }
+
+       /*
+        * Definitions MUST begin with an OID in the numericoid format.
+        * However, this routine is used by clients to parse the response
+        * from servers and very well known servers will provide an OID
+        * in the wrong format or even no OID at all.  We do our best to
+        * extract info from those servers.
+        */
+       parse_whsp(&ss);
+       savepos = ss;
+       cr->cr_oid = ldap_int_parse_numericoid(&ss,code,0);
+       if ( !cr->cr_oid ) {
+               if ( (flags & LDAP_SCHEMA_ALLOW_ALL) && (ss == savepos) ) {
+                       /* Backtracking */
+                       ss = savepos;
+                       kind = get_token(&ss,&sval);
+                       if ( kind == TK_BAREWORD ) {
+                               if ( !strcmp(sval, "NAME") ||
+                                    !strcmp(sval, "DESC") ||
+                                    !strcmp(sval, "OBSOLETE") ||
+                                    !strcmp(sval, "AUX") ||
+                                    !strcmp(sval, "MUST") ||
+                                    !strcmp(sval, "MAY") ||
+                                    !strcmp(sval, "NOT") ||
+                                    !strncmp(sval, "X-", 2) ) {
+                                       /* Missing OID, backtrack */
+                                       ss = savepos;
+                               } else if ( flags &
+                                       LDAP_SCHEMA_ALLOW_OID_MACRO ) {
+                                       /* Non-numerical OID, ignore */
+                                       int len = ss-savepos;
+                                       cr->cr_oid = LDAP_MALLOC(len+1);
+                                       strncpy(cr->cr_oid, savepos, len);
+                                       cr->cr_oid[len] = 0;
+                               }
+                       }
+                       LDAP_FREE(sval);
+               } else {
+                       *errp = ss;
+                       ldap_contentrule_free(cr);
+                       return NULL;
+               }
+       }
+       parse_whsp(&ss);
+
+       /*
+        * Beyond this point we will be liberal an accept the items
+        * in any order.
+        */
+       while (1) {
+               kind = get_token(&ss,&sval);
+               switch (kind) {
+               case TK_EOS:
+                       *code = LDAP_SCHERR_NORIGHTPAREN;
+                       *errp = ss;
+                       ldap_contentrule_free(cr);
+                       return NULL;
+               case TK_RIGHTPAREN:
+                       return cr;
+               case TK_BAREWORD:
+                       if ( !strcmp(sval,"NAME") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_name ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_name = 1;
+                               cr->cr_names = parse_qdescrs(&ss,code);
+                               if ( !cr->cr_names ) {
+                                       if ( *code != LDAP_SCHERR_OUTOFMEM )
+                                               *code = LDAP_SCHERR_BADNAME;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                       } else if ( !strcmp(sval,"DESC") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_desc ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_desc = 1;
+                               parse_whsp(&ss);
+                               kind = get_token(&ss,&sval);
+                               if ( kind != TK_QDSTRING ) {
+                                       *code = LDAP_SCHERR_UNEXPTOKEN;
+                                       *errp = ss;
+                                       LDAP_FREE(sval);
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               cr->cr_desc = sval;
+                               parse_whsp(&ss);
+                       } else if ( !strcmp(sval,"OBSOLETE") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_obsolete ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_obsolete = 1;
+                               cr->cr_obsolete = LDAP_SCHEMA_YES;
+                               parse_whsp(&ss);
+                       } else if ( !strcmp(sval,"AUX") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_aux ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_aux = 1;
+                               cr->cr_oc_oids_aux = parse_oids(&ss,code,0);
+                               if ( !cr->cr_oc_oids_aux ) {
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               parse_whsp(&ss);
+                       } else if ( !strcmp(sval,"MUST") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_must ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_must = 1;
+                               cr->cr_at_oids_must = parse_oids(&ss,code,0);
+                               if ( !cr->cr_at_oids_must ) {
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               parse_whsp(&ss);
+                       } else if ( !strcmp(sval,"MAY") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_may ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_may = 1;
+                               cr->cr_at_oids_may = parse_oids(&ss,code,0);
+                               if ( !cr->cr_at_oids_may ) {
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               parse_whsp(&ss);
+                       } else if ( !strcmp(sval,"NOT") ) {
+                               LDAP_FREE(sval);
+                               if ( seen_not ) {
+                                       *code = LDAP_SCHERR_DUPOPT;
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return(NULL);
+                               }
+                               seen_not = 1;
+                               cr->cr_at_oids_not = parse_oids(&ss,code,0);
+                               if ( !cr->cr_at_oids_not ) {
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               parse_whsp(&ss);
+                       } else if ( sval[0] == 'X' && sval[1] == '-' ) {
+                               /* Should be parse_qdstrings */
+                               ext_vals = parse_qdescrs(&ss, code);
+                               if ( !ext_vals ) {
+                                       *errp = ss;
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                               if ( add_extension(&cr->cr_extensions,
+                                                   sval, ext_vals) ) {
+                                       *code = LDAP_SCHERR_OUTOFMEM;
+                                       *errp = ss;
+                                       LDAP_FREE(sval);
+                                       ldap_contentrule_free(cr);
+                                       return NULL;
+                               }
+                       } else {
+                               *code = LDAP_SCHERR_UNEXPTOKEN;
+                               *errp = ss;
+                               LDAP_FREE(sval);
+                               ldap_contentrule_free(cr);
+                               return NULL;
+                       }
+                       break;
+               default:
+                       *code = LDAP_SCHERR_UNEXPTOKEN;
+                       *errp = ss;
+                       LDAP_FREE(sval);
+                       ldap_contentrule_free(cr);
+                       return NULL;
+               }
+       }
+}
+
 static char *const err2text[] = {
        "Success",
        "Out of memory",
index 45b77f65281a421d0015b702471885f4ada0399f..e09ef637bec0e6f9d8b9db19bc48343b8cedb3ef 100644 (file)
@@ -110,6 +110,11 @@ ldap_ld_free(
                ld->ld_matched = NULL;
        }
 
+       if( ld->ld_referrals != NULL) {
+               LDAP_VFREE(ld->ld_referrals);
+               ld->ld_referrals = NULL;
+       }  
+    
        if ( ld->ld_abandoned != NULL ) {
                LDAP_FREE( ld->ld_abandoned );
                ld->ld_abandoned = NULL;