]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/attr.c
Add OpenLDAP RCSid to *.[ch] in clients, libraries, and servers.
[openldap] / servers / slapd / attr.c
index 3254b3d0aad99b868859d4895450556caaedf826..8a5f5358cb2f8d263937370fe0bdf455da94dbef 100644 (file)
@@ -1,3 +1,8 @@
+/* $OpenLDAP$ */
+/*
+ * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
 /* attr.c - routines for dealing with attributes */
 
 #include "portable.h"
@@ -18,8 +23,7 @@
 #include <sys/param.h>
 #endif
 
-#include <sys/stat.h>
-
+#include "ldap_pvt.h"
 #include "slap.h"
 
 #ifdef LDAP_DEBUG
@@ -34,6 +38,71 @@ attr_free( Attribute *a )
        free( a );
 }
 
+void
+attrs_free( Attribute *a )
+{
+       Attribute *next;
+
+       for( ; a != NULL ; a = next ) {
+               next = a->a_next;
+               attr_free( a );
+       }
+}
+
+Attribute *attr_dup( Attribute *a )
+{
+       Attribute *tmp;
+
+       if( a == NULL) return NULL;
+
+       tmp = ch_malloc( sizeof(Attribute) );
+
+       if( a->a_vals != NULL ) {
+               int i;
+
+               for( i=0; a->a_vals[i] != NULL; i++ ) {
+                       /* EMPTY */ ;
+               }
+
+               tmp->a_vals = ch_malloc((i+1) * sizeof(struct berval*));
+
+               for( i=0; a->a_vals[i] != NULL; i++ ) {
+                       tmp->a_vals[i] = ber_bvdup( a->a_vals[i] );
+
+                       if( tmp->a_vals[i] == NULL ) break;
+               }
+
+               tmp->a_vals[i] = NULL;
+
+       } else {
+               tmp->a_vals = NULL;
+       }
+
+       tmp->a_type = ch_strdup( a->a_type );
+       tmp->a_syntax = a->a_syntax;
+       tmp->a_next = NULL;
+
+       return tmp;
+}
+
+Attribute *attrs_dup( Attribute *a )
+{
+       Attribute *tmp, **next;
+
+       if( a == NULL ) return NULL;
+
+       tmp = NULL;
+       next = &tmp;
+
+       for( ; a != NULL ; a = a->a_next ) {
+               *next = attr_dup( a );
+               next = &((*next)->a_next);
+       }
+       *next = NULL;
+
+       return tmp;
+}
+
 /*
  * attr_normalize - normalize an attribute name (make it all lowercase)
  */
@@ -41,15 +110,9 @@ attr_free( Attribute *a )
 char *
 attr_normalize( char *s )
 {
-       char    *save;
-
        assert( s != NULL );
 
-       for ( save = s; *s; s++ ) {
-               *s = TOLOWER( (unsigned char) *s );
-       }
-
-       return( save );
+       return( ldap_pvt_str2lower( s ) );
 }
 
 /*
@@ -131,7 +194,7 @@ attr_merge(
 Attribute *
 attr_find(
     Attribute  *a,
-    char       *type
+    const char *type
 )
 {
        for ( ; a != NULL; a = a->a_next ) {
@@ -153,7 +216,7 @@ attr_find(
 int
 attr_delete(
     Attribute  **attrs,
-    char       *type
+    const char *type
 )
 {
        Attribute       **a;
@@ -178,62 +241,6 @@ attr_delete(
 
 #define DEFAULT_SYNTAX SYNTAX_CIS
 
-/* Force compilation errors by commenting out this
-struct asyntaxinfo {
-       char    **asi_names;
-       int     asi_syntax;
-};
-static Avlnode *attr_syntaxes = NULL;
-
-static int
-attr_syntax_cmp(
-    struct asyntaxinfo        *a1,
-    struct asyntaxinfo        *a2
-)
-{
-      return( strcasecmp( a1->asi_names[0], a2->asi_names[0] ) );
-}
-
-static int
-attr_syntax_name_cmp(
-    char               *type,
-    struct asyntaxinfo *a
-)
-{
-       return( strcasecmp( type, a->asi_names[0] ) );
-}
-
-static int
-attr_syntax_names_cmp(
-    char               *type,
-    struct asyntaxinfo *a
-)
-{
-       int     i;
-
-       for ( i = 0; a->asi_names[i] != NULL; i++ ) {
-               if ( strcasecmp( type, a->asi_names[i] ) == 0 ) {
-                       return( 0 );
-               }
-       }
-       return( 1 );
-}
-
-static int
-attr_syntax_dup(
-    struct asyntaxinfo        *a1,
-    struct asyntaxinfo        *a2
-)
-{
-       if ( a1->asi_syntax != a2->asi_syntax ) {
-               return( -1 );
-       }
-
-       return( 1 );
-}
-
-*/
-
 /*
  * attr_syntax - return the syntax of attribute type
  */
@@ -257,7 +264,7 @@ attr_syntax( char *type )
 
 void
 attr_syntax_config(
-    char       *fname,
+    const char *fname,
     int                lineno,
     int                argc,
     char       **argv
@@ -267,7 +274,7 @@ attr_syntax_config(
        LDAP_ATTRIBUTE_TYPE     *at;
        int                     lasti;
        int                     code;
-       char                    *err;
+       const char              *err;
 
        if ( argc < 2 ) {
                Debug( LDAP_DEBUG_ANY,
@@ -284,18 +291,22 @@ attr_syntax_config(
            strcasecmp( argv[lasti], "cis" ) == 0 ) {
                at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
                at->at_equality_oid = "2.5.13.2";
+               at->at_ordering_oid = "2.5.13.3";
+               at->at_substr_oid = "2.5.13.4";
        } else if ( strcasecmp( argv[lasti], "telephone" ) == 0 ||
            strcasecmp( argv[lasti], "tel" ) == 0 ) {
                at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.50";
                at->at_equality_oid = "2.5.13.20";
+               at->at_substr_oid = "2.5.13.21";
        } else if ( strcasecmp( argv[lasti], "dn" ) == 0 ) {
                at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.12";
                at->at_equality_oid = "2.5.13.1";
        } else if ( strcasecmp( argv[lasti], "caseexactstring" ) == 0 ||
            strcasecmp( argv[lasti], "ces" ) == 0 ) {
                at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.15";
-               /* notice: this is caseExactIA5Match */
-               at->at_equality_oid = "1.3.6.1.4.1.1466.109.114.1";
+               at->at_equality_oid = "2.5.13.5";
+               at->at_ordering_oid = "2.5.13.6";
+               at->at_substr_oid = "2.5.13.7";
        } else if ( strcasecmp( argv[lasti], "binary" ) == 0 ||
            strcasecmp( argv[lasti], "bin" ) == 0 ) {
                at->at_syntax_oid = "1.3.6.1.4.1.1466.115.121.1.5";
@@ -320,7 +331,7 @@ attr_syntax_config(
        if ( code ) {
                fprintf( stderr, "%s: line %d: %s %s\n",
                         fname, lineno, scherr2str(code), err);
-               exit( 1 );
+               exit( EXIT_FAILURE );
        }
        ldap_memfree(at);
 }
@@ -371,7 +382,7 @@ attr_index_name_cmp(
 
 AttributeType *
 at_find(
-    char               *name
+    const char         *name
 )
 {
        struct aindexrec        *air = NULL;
@@ -475,7 +486,7 @@ at_find_in_list(
 static int
 at_insert(
     AttributeType      *sat,
-    char               **err
+    const char         **err
 )
 {
        AttributeType           **atp;
@@ -488,22 +499,22 @@ at_insert(
        }
        *atp = sat;
 
-       if ( sat->sat_atype.at_oid ) {
+       if ( sat->sat_oid ) {
                air = (struct aindexrec *)
                        ch_calloc( 1, sizeof(struct aindexrec) );
-               air->air_name = sat->sat_atype.at_oid;
+               air->air_name = sat->sat_oid;
                air->air_at = sat;
                if ( avl_insert( &attr_index, (caddr_t) air,
                                 (AVL_CMP) attr_index_cmp,
                                 (AVL_DUP) avl_dup_error ) ) {
-                       *err = sat->sat_atype.at_oid;
+                       *err = sat->sat_oid;
                        ldap_memfree(air);
                        return SLAP_SCHERR_DUP_ATTR;
                }
                /* FIX: temporal consistency check */
                at_find(air->air_name);
        }
-       if ( (names = sat->sat_atype.at_names) ) {
+       if ( (names = sat->sat_names) ) {
                while ( *names ) {
                        air = (struct aindexrec *)
                                ch_calloc( 1, sizeof(struct aindexrec) );
@@ -528,18 +539,23 @@ at_insert(
 int
 at_add(
     LDAP_ATTRIBUTE_TYPE        *at,
-    char               **err
+    const char         **err
 )
 {
        AttributeType   *sat;
        AttributeType   *sat1;
+       MatchingRule    *mr;
+       Syntax          *syn;
        int             code;
        char            *errattr;
 
        if ( at->at_names && at->at_names[0] ) {
                errattr = at->at_names[0];
-       } else {
+       } else if ( at->at_oid ) {
                errattr = at->at_oid;
+       } else {
+               errattr = "";
+               return SLAP_SCHERR_ATTR_INCOMPLETE;
        }
        sat = (AttributeType *) ch_calloc( 1, sizeof(AttributeType) );
        memcpy( &sat->sat_atype, at, sizeof(LDAP_ATTRIBUTE_TYPE));
@@ -551,33 +567,147 @@ at_add(
                                return SLAP_SCHERR_OUTOFMEM;
                        }
                } else {
-                       *err = errattr;
+                       *err = at->at_sup_oid;
                        return SLAP_SCHERR_ATTR_NOT_FOUND;
                }
        }
 
-       if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.15") ) {
-               if ( !strcmp(at->at_equality_oid,
-                            "1.3.6.1.4.1.1466.109.114.1") ) {
-                       sat->sat_syntax_compat = SYNTAX_CES;
+       if ( at->at_syntax_oid ) {
+               if ( (syn = syn_find(sat->sat_syntax_oid)) ) {
+                       sat->sat_syntax = syn;
                } else {
-                       sat->sat_syntax_compat = SYNTAX_CIS;
+                       *err = sat->sat_syntax_oid;
+                       return SLAP_SCHERR_SYN_NOT_FOUND;
+               }
+               if ( !strcmp(at->at_syntax_oid,
+                            "1.3.6.1.4.1.1466.115.121.1.15") ) {
+                       if ( at->at_equality_oid &&
+                            !strcmp(at->at_equality_oid, "2.5.13.5") ) {
+                               sat->sat_syntax_compat = SYNTAX_CES;
+                       } else {
+                               sat->sat_syntax_compat = SYNTAX_CIS;
+                       }
+               } else if ( !strcmp(at->at_syntax_oid,
+                                   "1.3.6.1.4.1.1466.115.121.1.50") ) {
+                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
+               } else if ( !strcmp(at->at_syntax_oid,
+                                   "1.3.6.1.4.1.1466.115.121.1.12") ) {
+                       sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
+               } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
+                       sat->sat_syntax_compat = SYNTAX_BIN;
+               } else {
+                       sat->sat_syntax_compat = DEFAULT_SYNTAX;
                }
-       } else if ( !strcmp(at->at_syntax_oid,
-                           "1.3.6.1.4.1.1466.115.121.1.50") ) {
-               sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_TEL;
-       } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.12") ) {
-               sat->sat_syntax_compat = SYNTAX_CIS | SYNTAX_DN;
-       } else if ( !strcmp(at->at_syntax_oid, "1.3.6.1.4.1.1466.115.121.1.5") ) {
-               sat->sat_syntax_compat = SYNTAX_BIN;
        } else {
                sat->sat_syntax_compat = DEFAULT_SYNTAX;
        }
 
+       if ( sat->sat_equality_oid ) {
+               if ( (mr = mr_find(sat->sat_equality_oid)) ) {
+                       sat->sat_equality = mr;
+               } else {
+                       *err = sat->sat_equality_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+       if ( sat->sat_ordering_oid ) {
+               if ( (mr = mr_find(sat->sat_ordering_oid)) ) {
+                       sat->sat_ordering = mr;
+               } else {
+                       *err = sat->sat_ordering_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+       if ( sat->sat_substr_oid ) {
+               if ( (mr = mr_find(sat->sat_substr_oid)) ) {
+                       sat->sat_substr = mr;
+               } else {
+                       *err = sat->sat_substr_oid;
+                       return SLAP_SCHERR_MR_NOT_FOUND;
+               }
+       }
+
+       /*
+        * Now inherit definitions from superiors.  We only check the
+        * direct superior since that one has already inherited from
+        * its own superiorss
+        */
+       if ( sat->sat_sup ) {
+               if ( !sat->sat_syntax ) {
+                       sat->sat_syntax = sat->sat_sup->sat_syntax;
+                       sat->sat_syntax_len = sat->sat_sup->sat_syntax_len;
+               }
+               if ( !sat->sat_equality ) {
+                       sat->sat_equality = sat->sat_sup->sat_equality;
+               }
+               if ( !sat->sat_ordering ) {
+                       sat->sat_ordering = sat->sat_sup->sat_ordering;
+               }
+               if ( !sat->sat_substr ) {
+                       sat->sat_substr = sat->sat_sup->sat_substr;
+               }
+       }
        code = at_insert(sat,err);
        return code;
 }
 
+
+char *
+at_canonical_name( char * a_type )
+{
+       AttributeType   *atp;
+
+       if ( (atp=at_find(a_type)) == NULL ) {
+
+               return a_type;
+
+       } else  if ( atp->sat_names 
+                    && atp->sat_names[0]
+                    && (*(atp->sat_names[0]) != '\0') ) {
+           
+               return atp->sat_names[0];
+
+       } else if (atp->sat_oid && (*atp->sat_oid != '\0')) {
+
+               return atp->sat_oid;
+               
+       } else {
+
+               return a_type;
+
+       }
+
+}/* char * at_canonica_name() */
+
+
+#if defined( SLAPD_SCHEMA_DN )
+
+int
+at_schema_info( Entry *e )
+{
+       struct berval   val;
+       struct berval   *vals[2];
+       AttributeType   *at;
+
+       vals[0] = &val;
+       vals[1] = NULL;
+
+       for ( at = attr_list; at; at = at->sat_next ) {
+               val.bv_val = ldap_attributetype2str( &at->sat_atype );
+               if ( val.bv_val ) {
+                       val.bv_len = strlen( val.bv_val );
+                       Debug( LDAP_DEBUG_TRACE, "Merging at [%ld] %s\n",
+                              (long) val.bv_len, val.bv_val, 0 );
+                       attr_merge( e, "attributeTypes", vals );
+                       ldap_memfree( val.bv_val );
+               } else {
+                       return -1;
+               }
+       }
+       return 0;
+}
+#endif
+
 #ifdef LDAP_DEBUG
 
 static int