]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/schema_init.c
Cleanup
[openldap] / servers / slapd / schema_init.c
index 28f2498a422c51b65f2382912fbdab0d4db93b54..55fc2fa8888127464fae42dd5fbb0a67cff5ff17 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2008 The OpenLDAP Foundation.
+ * Copyright 1998-2009 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -156,8 +156,8 @@ enum {
 
 enum {
        SLAP_X509_OPT_C_VERSION         = SLAP_X509_OPTION + 0,
-       SLAP_X509_OPT_C_ISSUERUNIQUEID  = SLAP_X509_OPTION + 1,
-       SLAP_X509_OPT_C_SUBJECTUNIQUEID = SLAP_X509_OPTION + 2,
+       SLAP_X509_OPT_C_ISSUERUNIQUEID  = LBER_CLASS_CONTEXT + 1,
+       SLAP_X509_OPT_C_SUBJECTUNIQUEID = LBER_CLASS_CONTEXT + 2,
        SLAP_X509_OPT_C_EXTENSIONS      = SLAP_X509_OPTION + 3
 };
 
@@ -273,18 +273,25 @@ certificateValidate( Syntax *syntax, struct berval *in )
 }
 
 /* X.509 certificate list validation */
+static int
+checkTime( struct berval *in, struct berval *out );
+
 static int
 certificateListValidate( Syntax *syntax, struct berval *in )
 {
        BerElementBuffer berbuf;
        BerElement *ber = (BerElement *)&berbuf;
        ber_tag_t tag;
-       ber_len_t len;
+       ber_len_t len, wrapper_len;
+       char *wrapper_start;
+       int wrapper_ok = 0;
        ber_int_t version = SLAP_X509_V1;
+       struct berval bvdn, bvtu;
 
        ber_init2( ber, in, LBER_USE_DER );
-       tag = ber_skip_tag( ber, &len );        /* Signed wrapper */
+       tag = ber_skip_tag( ber, &wrapper_len );        /* Signed wrapper */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       wrapper_start = ber->ber_ptr;
        tag = ber_skip_tag( ber, &len );        /* Sequence */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
        tag = ber_peek_tag( ber, &len );
@@ -297,12 +304,18 @@ certificateListValidate( Syntax *syntax, struct berval *in )
        tag = ber_skip_tag( ber, &len );        /* Signature Algorithm */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
        ber_skip_data( ber, len );
-       tag = ber_skip_tag( ber, &len );        /* Issuer DN */
+       tag = ber_peek_tag( ber, &len );        /* Issuer DN */
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
+       len = ber_ptrlen( ber );
+       bvdn.bv_val = in->bv_val + len;
+       bvdn.bv_len = in->bv_len - len;
+       tag = ber_skip_tag( ber, &len );
        ber_skip_data( ber, len );
        tag = ber_skip_tag( ber, &len );        /* thisUpdate */
        /* Time is a CHOICE { UTCTime, GeneralizedTime } */
        if ( tag != SLAP_TAG_UTCTIME && tag != SLAP_TAG_GENERALIZEDTIME ) return LDAP_INVALID_SYNTAX;
+       bvtu.bv_val = (char *)ber->ber_ptr;
+       bvtu.bv_len = len;
        ber_skip_data( ber, len );
        /* Optional nextUpdate */
        tag = ber_skip_tag( ber, &len );
@@ -319,10 +332,11 @@ certificateListValidate( Syntax *syntax, struct berval *in )
                        tag = ber_skip_tag( ber, &len );
                }
        }
-       /* Optional Extensions */
+       /* Optional Extensions - Sequence of Sequence */
        if ( tag == SLAP_X509_OPT_CL_CRLEXTENSIONS ) { /* ? */
+               ber_len_t seqlen;
                if ( version != SLAP_X509_V2 ) return LDAP_INVALID_SYNTAX;
-               tag = ber_skip_tag( ber, &len );
+               tag = ber_peek_tag( ber, &seqlen );
                if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
                ber_skip_data( ber, len );
                tag = ber_skip_tag( ber, &len );
@@ -334,9 +348,44 @@ certificateListValidate( Syntax *syntax, struct berval *in )
        /* Signature */
        if ( tag != LBER_BITSTRING ) return LDAP_INVALID_SYNTAX; 
        ber_skip_data( ber, len );
+       if ( ber->ber_ptr == wrapper_start + wrapper_len ) wrapper_ok = 1;
        tag = ber_skip_tag( ber, &len );
        /* Must be at end now */
-       if ( len || tag != LBER_DEFAULT ) return LDAP_INVALID_SYNTAX;
+       /* NOTE: OpenSSL tolerates CL with garbage past the end */
+       if ( len || tag != LBER_DEFAULT ) {
+               struct berval issuer_dn = BER_BVNULL, thisUpdate;
+               char tubuf[STRLENOF("YYYYmmddHHMMSSZ") + 1];
+               int rc;
+
+               if ( ! wrapper_ok ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               rc = dnX509normalize( &bvdn, &issuer_dn );
+               if ( rc != LDAP_SUCCESS ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               thisUpdate.bv_val = tubuf;
+               thisUpdate.bv_len = sizeof(tubuf); 
+               if ( checkTime( &bvtu, &thisUpdate ) ) {
+                       rc = LDAP_INVALID_SYNTAX;
+                       goto done;
+               }
+
+               Debug( LDAP_DEBUG_ANY,
+                       "certificateListValidate issuer=\"%s\", thisUpdate=%s: extra cruft past end of certificateList\n",
+                       issuer_dn.bv_val, thisUpdate.bv_val, 0 );
+
+done:;
+               if ( ! BER_BVISNULL( &issuer_dn ) ) {
+                       ber_memfree( issuer_dn.bv_val );
+               }
+
+               return rc;
+       }
+
        return LDAP_SUCCESS;
 }
 
@@ -388,7 +437,7 @@ attributeCertificateValidate( Syntax *syntax, struct berval *in )
        if ( tag != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX;
        ber_skip_data( ber, len );
 
-       ber_peek_tag( ber, &len );
+       tag = ber_peek_tag( ber, &len );
 
        if ( tag == LBER_BITSTRING ) {  /* issuerUniqueID */
                tag = ber_skip_tag( ber, &len );
@@ -1105,12 +1154,7 @@ bitStringValidate(
   ...
       
  *
- * Note: normalization strips any leading "0"s, unless the
- * bit string is exactly "'0'B", so the normalized example,
- * in slapd, would result in
- * 
- * 1.3.6.1.4.1.1466.0=#04024869,o=test,c=gb#'101'B
- * 
+ * Note:
  * RFC 4514 clarifies that SHARP, i.e. "#", doesn't have to
  * be escaped except when at the beginning of a value, the
  * definition of Name and Optional UID appears to be flawed,
@@ -1134,11 +1178,11 @@ bitStringValidate(
  *
  * in fact "com#'1'B" is a valid IA5 string.
  *
- * As a consequence, current slapd code assumes that the
- * presence of portions of a BitString at the end of the string 
- * representation of a NameAndOptionalUID means a BitString
- * is expected, and cause an error otherwise.  This is quite
- * arbitrary, and might change in the future.
+ * As a consequence, current slapd code takes the presence of
+ * #<valid BitString> at the end of the string representation
+ * of a NameAndOptionalUID to mean this is indeed a BitString.
+ * This is quite arbitrary - it has changed the past and might
+ * change in the future.
  */
 
 
@@ -1209,7 +1253,8 @@ nameUIDPretty(
 
                        if ( rc == LDAP_SUCCESS ) {
                                ber_dupbv_x( &dnval, val, ctx );
-                               dnval.bv_len -= uidval.bv_len + 1;
+                               uidval.bv_val--;
+                               dnval.bv_len -= ++uidval.bv_len;
                                dnval.bv_val[dnval.bv_len] = '\0';
 
                        } else {
@@ -1226,36 +1271,18 @@ nameUIDPretty(
                }
 
                if( !BER_BVISNULL( &uidval ) ) {
-                       int     i, c, got1;
                        char    *tmp;
 
                        tmp = slap_sl_realloc( out->bv_val, out->bv_len 
-                               + STRLENOF( "#" ) + uidval.bv_len + 1,
+                               + uidval.bv_len + 1,
                                ctx );
                        if( tmp == NULL ) {
                                ber_memfree_x( out->bv_val, ctx );
                                return LDAP_OTHER;
                        }
                        out->bv_val = tmp;
-                       out->bv_val[out->bv_len++] = '#';
-                       out->bv_val[out->bv_len++] = '\'';
-
-                       got1 = uidval.bv_len < sizeof("'0'B"); 
-                       for( i = 1; i < uidval.bv_len - 2; i++ ) {
-                               c = uidval.bv_val[i];
-                               switch(c) {
-                                       case '0':
-                                               if( got1 ) out->bv_val[out->bv_len++] = c;
-                                               break;
-                                       case '1':
-                                               got1 = 1;
-                                               out->bv_val[out->bv_len++] = c;
-                                               break;
-                               }
-                       }
-
-                       out->bv_val[out->bv_len++] = '\'';
-                       out->bv_val[out->bv_len++] = 'B';
+                       memcpy( out->bv_val + out->bv_len, uidval.bv_val, uidval.bv_len );
+                       out->bv_len += uidval.bv_len;
                        out->bv_val[out->bv_len] = '\0';
                }
        }
@@ -2238,7 +2265,7 @@ postalAddressNormalize(
 
        p = normalized->bv_val;
        for ( l = 0; !BER_BVISNULL( &nlines[l] ); l++ ) {
-               p = lutil_strncopy( p, nlines[l].bv_val, nlines[l].bv_len );
+               p = lutil_memcopy( p, nlines[l].bv_val, nlines[l].bv_len );
 
                *p++ = '$';
        }
@@ -2836,6 +2863,7 @@ UUIDNormalize(
 
                } else {
                        slap_sl_free( normalized->bv_val, ctx );
+                       BER_BVZERO( normalized );
                        return LDAP_INVALID_SYNTAX;
                }
 
@@ -3637,6 +3665,9 @@ checkTime( struct berval *in, struct berval *out )
 
        rc = generalizedTimeValidate( NULL, &bv );
        if ( rc == LDAP_SUCCESS && out != NULL ) {
+               if ( out->bv_len > bv.bv_len ) {
+                       out->bv_val[ bv.bv_len ] = '\0';
+               }
                out->bv_len = bv.bv_len;
        }
 
@@ -4385,8 +4416,8 @@ serialNumberAndIssuerSerialCheck(
                ber_dupbv_x( &ni, is, ctx );
 
        } else {
-               ber_int_t src, dst;
-               
+               ber_len_t src, dst;
+
                ni.bv_len = is->bv_len - numdquotes;
                ni.bv_val = ber_memalloc_x( ni.bv_len + 1, ctx );
                for ( src = 0, dst = 0; src < is->bv_len; src++, dst++ ) {
@@ -6647,7 +6678,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
        {"( 1.3.6.1.4.1.4203.666.11.2.3 NAME 'CSNOrderingMatch' "
                "SYNTAX 1.3.6.1.4.1.4203.666.11.2.1 )",
                SLAP_MR_HIDE | SLAP_MR_ORDERING | SLAP_MR_ORDERED_INDEX, NULL,
-               NULL, NULL, csnOrderingMatch,
+               NULL, csnNormalize, csnOrderingMatch,
                NULL, NULL,
                "CSNMatch" },