]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/dn.c
Added connection initialisation and destruction notification. Now backends can regist...
[openldap] / servers / slapd / dn.c
index d67aca70acb54293f011788fed664b829ca7d9f8..4f28d164b8989490de6b653ce3aa95a3328986c9 100644 (file)
 
 #include "slap.h"
 
-static char    **dn_explode();
-
-#define DNSEPARATOR(c) (c == ',' || c == ';')
-#define SEPARATOR(c)   (c == ',' || c == ';' || c == '+')
-#define SPACE(c)       (c == ' ' || c == '\n')
-#define NEEDSESCAPE(c) (c == '\\' || c == '"')
 #define B4TYPE         0
 #define INTYPE         1
 #define B4EQUAL                2
@@ -144,7 +138,7 @@ dn_normalize_case( char *dn )
 
        /* normalize case */
        for ( s = dn; *s; s++ ) {
-               *s = TOUPPER( *s );
+               *s = TOUPPER( (unsigned char) *s );
        }
 
        return( dn );
@@ -161,9 +155,21 @@ dn_parent(
 )
 {
        char    *s;
-       int     inquote, gotesc;
+       int     inquote;
+
+       if( dn == NULL ) {
+               return NULL;
+       }
+
+       while(*dn && SPACE(*dn)) {
+               dn++;
+       }
+
+       if( *dn == '\0' ) {
+               return( NULL );
+       }
 
-       if ( dn == NULL || *dn == '\0' || be_issuffix( be, dn ) ) {
+       if ( be != NULL && be_issuffix( be, dn ) ) {
                return( NULL );
        }
 
@@ -181,8 +187,77 @@ dn_parent(
                if ( *(s + 1) == '\0' ) {
                        return( NULL );
                } else {
-                       return( strdup( s + 1 ) );
+                       return( ch_strdup( &s[1] ) );
+               }
+       }
+
+       /*
+        * else assume it is an X.500-style name, which looks like
+        * foo=bar,sha=baz,...
+        */
+
+       inquote = 0;
+       for ( s = dn; *s; s++ ) {
+               if ( *s == '\\' ) {
+                       if ( *(s + 1) ) {
+                               s++;
+                       }
+                       continue;
+               }
+               if ( inquote ) {
+                       if ( *s == '"' ) {
+                               inquote = 0;
+                       }
+               } else {
+                       if ( *s == '"' ) {
+                               inquote = 1;
+                       } else if ( DNSEPARATOR( *s ) ) {
+                               return( ch_strdup( &s[1] ) );
+                       }
+               }
+       }
+
+       return( ch_strdup( "" ) );
+}
+
+char * dn_rdn( 
+    Backend    *be,
+    char       *dn )
+{
+       char    *s;
+       int     inquote;
+
+       if( dn == NULL ) {
+               return NULL;
+       }
+
+       while(*dn && SPACE(*dn)) {
+               dn++;
+       }
+
+       if( *dn == '\0' ) {
+               return( NULL );
+       }
+
+       if ( be != NULL && be_issuffix( be, dn ) ) {
+               return( NULL );
+       }
+
+       dn = ch_strdup( dn );
+
+       /*
+        * no =, assume it is a dns name, like blah@some.domain.name
+        * if the blah@ part is there, return some.domain.name.  if
+        * it's just some.domain.name, return domain.name.
+        */
+       if ( strchr( dn, '=' ) == NULL ) {
+               if ( (s = strchr( dn, '@' )) == NULL ) {
+                       if ( (s = strchr( dn, '.' )) == NULL ) {
+                               return( dn );
+                       }
                }
+               *s = '\0';
+               return( dn );
        }
 
        /*
@@ -191,24 +266,29 @@ dn_parent(
         */
 
        inquote = 0;
+
        for ( s = dn; *s; s++ ) {
                if ( *s == '\\' ) {
-                       if ( *(s + 1) )
+                       if ( *(s + 1) ) {
                                s++;
+                       }
                        continue;
                }
                if ( inquote ) {
-                       if ( *s == '"' )
+                       if ( *s == '"' ) {
                                inquote = 0;
+                       }
                } else {
-                       if ( *s == '"' )
+                       if ( *s == '"' ) {
                                inquote = 1;
-                       else if ( DNSEPARATOR( *s ) )
-                               return( strdup( s + 1 ) );
+                       } else if ( DNSEPARATOR( *s ) ) {
+                               *s = '\0';
+                               return( dn );
+                       }
                }
        }
 
-       return( strdup("") );
+       return( dn );
 }
 
 /*
@@ -235,7 +315,7 @@ dn_issuffix(
                return( 0 );
        }
 
-       return( strcasecmp( dn + dnlen - suffixlen, suffix ) == 0 );
+       return( strcmp( dn + dnlen - suffixlen, suffix ) == 0 );
 }
 
 /*
@@ -257,8 +337,162 @@ dn_upcase( char *dn )
 
        /* normalize case */
        for ( s = dn; *s; s++ ) {
-               *s = TOUPPER( *s );
+               *s = TOUPPER( (unsigned char) *s );
        }
 
        return( dn );
 }
+
+
+/*
+ * get_next_substring(), rdn_attr_type(), rdn_attr_value(), and
+ * build_new_dn().
+ * 
+ * Copyright 1999, Juan C. Gomez, All rights reserved.
+ * This software is not subject to any license of Silicon Graphics 
+ * Inc. or Purdue University.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * without restriction or fee of any kind as long as this notice
+ * is preserved.
+ *
+ */
+
+/* get_next_substring:
+ *
+ * Gets next substring in s, using d (or the end of the string '\0') as a 
+ * string delimiter, and places it in a duplicated memory space. Leading 
+ * spaces are ignored. String s **must** be null-terminated.
+ */ 
+
+static char * 
+get_next_substring( char * s, char d )
+{
+
+       char    *str, *r;
+
+       r = str = ch_malloc( strlen(s) + 1 );
+
+       /* Skip leading spaces */
+       
+       while ( *s && SPACE(*s) ) {
+           
+               s++;
+           
+       }/* while ( *s && SPACE(*s) ) */
+       
+       /* Copy word */
+
+       while ( *s && (*s != d) ) {
+
+               /* Don't stop when you see trailing spaces may be a multi-word
+               * string, i.e. name=John Doe!
+               */
+
+               *str++ = *s++;
+           
+       }/* while ( *s && (*s != d) ) */
+       
+       *str = '\0';
+       
+       return r;
+       
+}/* char * get_word() */
+
+
+/* rdn_attr_type:
+ *
+ * Given a string (i.e. an rdn) of the form:
+ *      "attribute_type = attribute_value"
+ * this function returns the type of an attribute, that is the 
+ * string "attribute_type" which is placed in newly allocated 
+ * memory. The returned string will be null-terminated.
+ */
+
+char * rdn_attr_type( char * s )
+{
+
+       return get_next_substring( s, '=' );
+
+}/* char * rdn_attr_type() */
+
+
+/* rdn_attr_value:
+ *
+ * Given a string (i.e. an rdn) of the form:
+ *      "attribute_type = attribute_value"
+ * this function returns "attribute_type" which is placed in newly allocated 
+ * memory. The returned string will be null-terminated and may contain 
+ * spaces (i.e. "John Doe\0").
+ */
+
+char * 
+rdn_attr_value( char * rdn )
+{
+
+       char    *str;
+
+       if ( (str = strchr( rdn, '=' )) != NULL ) {
+
+               return get_next_substring(++str, '\0');
+
+       }/* if ( (str = strpbrk( rdn, "=" )) != NULL ) */
+
+       return NULL;
+
+}/* char * rdn_attr_value() */
+
+
+/* build_new_dn:
+ *
+ * Used by ldbm/bdb2_back_modrdn to create the new dn of entries being
+ * renamed.
+ *
+ * new_dn = parent (p_dn)  + separator(s) + rdn (newrdn) + null.
+ */
+
+void
+build_new_dn( char ** new_dn, char *e_dn, char * p_dn, char * newrdn )
+{
+
+    if ( p_dn == NULL ) {
+
+       *new_dn = ch_strdup( newrdn );
+       return;
+
+    }
+    
+    *new_dn = (char *) ch_malloc( strlen( p_dn ) + strlen( newrdn ) + 3 );
+
+    if ( dn_type( e_dn ) == DN_X500 ) {
+
+       strcpy( *new_dn, newrdn );
+       strcat( *new_dn, "," );
+       strcat( *new_dn, p_dn );
+
+    } else {
+
+       char    *s;
+       char    sep[2];
+
+       strcpy( *new_dn, newrdn );
+       s = strchr( newrdn, '\0' );
+       s--;
+
+       if ( (*s != '.') && (*s != '@') ) {
+
+           if ( (s = strpbrk( e_dn, ".@" )) != NULL ) {
+
+               sep[0] = *s;
+               sep[1] = '\0';
+               strcat( *new_dn, sep );
+
+           }/* if ( (s = strpbrk( dn, ".@" )) != NULL ) */
+
+       }/* if ( *s != '.' && *s != '@' ) */
+
+       strcat( *new_dn, p_dn );
+
+    }/* if ( dn_type( e_dn ) == DN_X500 ) {}else */
+    
+}/* void build_new_dn() */