X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdn.c;h=8b0c5cb18755bec0a3846b976f30c7e7e01ef6e9;hb=a6883d270464bb74e86141435dc4324e5a5a6b6a;hp=226937efa99f521a9c0cf0d6ef98deeb631f7fe7;hpb=42e0d83cb3a1a1c5b25183f1ab74ce7edbe25de7;p=openldap diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index 226937efa9..8b0c5cb187 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -1,20 +1,16 @@ /* dn.c - routines for dealing with distinguished names */ -#include -#include -#include -#include -#include -#include #include "portable.h" -#include "slap.h" -static char **dn_explode(); +#include + +#include +#include +#include +#include + +#include "slap.h" -#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 @@ -142,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,7 +157,19 @@ dn_parent( char *s; int inquote, gotesc; - if ( dn == NULL || *dn == '\0' || be_issuffix( be, dn ) ) { + if( dn == NULL ) { + return NULL; + } + + while(*dn && SPACE(*dn)) { + dn++; + } + + if( *dn == '\0' ) { + return( NULL ); + } + + if ( be_issuffix( be, dn ) ) { return( NULL ); } @@ -179,7 +187,7 @@ dn_parent( if ( *(s + 1) == '\0' ) { return( NULL ); } else { - return( strdup( s + 1 ) ); + return( ch_strdup( &s[1] ) ); } } @@ -191,22 +199,96 @@ 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 ) ) { + return( ch_strdup( &s[1] ) ); + } } } - return( NULL ); + 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 ); + } + + /* + * 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 ) ) { + *s = '\0'; + return( dn ); + } + } + } + + return( dn ); } /* @@ -233,7 +315,7 @@ dn_issuffix( return( 0 ); } - return( strcasecmp( dn + dnlen - suffixlen, suffix ) == 0 ); + return( strcmp( dn + dnlen - suffixlen, suffix ) == 0 ); } /* @@ -255,8 +337,161 @@ 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() */