3 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright (c) 1994 Regents of the University of Michigan.
17 #include <ac/stdlib.h>
20 #include <ac/socket.h>
21 #include <ac/string.h>
26 #define NAME_TYPE_LDAP_RDN 0
27 #define NAME_TYPE_LDAP_DN 1
28 #define NAME_TYPE_DCE_DN 2
30 static char **explode_name( const char *name, int notypes, int is_type );
33 ldap_get_dn( LDAP *ld, LDAPMessage *entry )
38 Debug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
40 if ( entry == NULL ) {
41 ld->ld_errno = LDAP_PARAM_ERROR;
45 tmp = *entry->lm_ber; /* struct copy */
46 if ( ber_scanf( &tmp, "{a" /*}*/, &dn ) == LBER_ERROR ) {
47 ld->ld_errno = LDAP_DECODING_ERROR;
55 ldap_dn2ufn( LDAP_CONST char *dn )
60 Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
66 if ( ldap_is_dns_dn( dn ) ||
67 ( p = ldap_utf8_strpbrk( dn, "=" ) ) == NULL )
69 return( LDAP_STRDUP( dn ) );
72 ufn = LDAP_STRDUP( ++p );
74 if( ufn == NULL ) return NULL;
79 for ( p = ufn, r = ufn; *p; LDAP_UTF8_INCR(p) ) {
84 LDAP_UTF8_COPY(r,++p);
90 if ( state == INQUOTE )
99 if ( state == OUTQUOTE )
106 if ( state == INQUOTE ) {
114 while ( !ldap_utf8_isspace( r )
115 && *r != ';' && *r != ',' && r > ufn )
121 if ( strcasecmp( r, "c" )
122 && strcasecmp( r, "o" )
123 && strcasecmp( r, "ou" )
124 && strcasecmp( r, "st" )
125 && strcasecmp( r, "l" )
126 && strcasecmp( r, "cn" ) ) {
134 LDAP_UTF8_COPY(r, p);
145 ldap_explode_dns( LDAP_CONST char *dn_in )
155 if ( (dn = LDAP_STRDUP( dn_in )) == NULL ) {
159 if ( (rdns = (char **) LDAP_MALLOC( maxcomps * sizeof(char *) )) == NULL ) {
165 for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL;
166 s = ldap_pvt_strtok( NULL, "@.", &tok_r ) )
168 if ( ncomps == maxcomps ) {
170 if ( (rdns = (char **) LDAP_REALLOC( rdns, maxcomps *
171 sizeof(char *) )) == NULL )
177 rdns[ncomps++] = LDAP_STRDUP( s );
184 rdns = (char **) LDAP_REALLOC( rdns, (ncomps+1) * sizeof(char*) );
189 ldap_explode_dn( LDAP_CONST char *dn, int notypes )
191 Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
193 if ( ldap_is_dns_dn( dn ) ) {
194 return( ldap_explode_dns( dn ) );
196 return explode_name( dn, notypes, NAME_TYPE_LDAP_DN );
200 ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
202 Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
203 return explode_name( rdn, notypes, NAME_TYPE_LDAP_RDN );
207 ldap_dn2dcedn( LDAP_CONST char *dn )
209 char *dce, *q, **rdns, **p;
212 Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
214 rdns = explode_name( dn, 0, NAME_TYPE_LDAP_DN );
215 if ( rdns == NULL ) {
219 for ( p = rdns; *p != NULL; p++ ) {
220 len += strlen( *p ) + 1;
223 q = dce = LDAP_MALLOC( len + 1 );
228 p--; /* get back past NULL */
230 for ( ; p != rdns; p-- ) {
245 ldap_dcedn2dn( LDAP_CONST char *dce )
247 char *dn, *q, **rdns, **p;
250 Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
252 rdns = explode_name( dce, 0, NAME_TYPE_DCE_DN );
253 if ( rdns == NULL ) {
259 for ( p = rdns; *p != NULL; p++ ) {
260 len += strlen( *p ) + 1;
263 q = dn = LDAP_MALLOC( len );
270 for ( ; p != rdns; p-- ) {
278 /* the name was fully qualified, thus the most-significant
279 * RDN was empty. trash the last comma */
283 /* the name was relative. copy the most significant RDN */
291 explode_name( const char *name, int notypes, int is_type )
293 const char *p, *q, *rdn;
295 int offset, state, have_equals, count = 0, endquote, len;
298 if(name == NULL) name = "";
300 /* skip leading whitespace */
301 while( ldap_utf8_isspace( name )) {
302 LDAP_UTF8_INCR( name );
317 if ( p[1] != '\0' ) {
318 offset = LDAP_UTF8_OFFSET(++p);
322 if ( state == INQUOTE )
328 if( state = OUTQUOTE ) have_equals++;
331 if (is_type == NAME_TYPE_LDAP_RDN)
335 if (is_type == NAME_TYPE_DCE_DN)
340 if (is_type == NAME_TYPE_LDAP_DN)
345 if ( state == OUTQUOTE ) {
349 if ( parts == NULL ) {
350 if (( parts = (char **)LDAP_MALLOC( 8
351 * sizeof( char *))) == NULL )
353 } else if ( count >= 8 ) {
354 if (( parts = (char **)LDAP_REALLOC( parts,
355 (count+1) * sizeof( char *)))
360 parts[ count ] = NULL;
364 for ( q = rdn; q < p && *q != '='; ++q ) {
376 if ( p[-1] == '"' ) {
384 if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
387 SAFEMEMCPY( parts[ count-1 ], rdn, len );
390 /* skip trailing spaces */
391 while( len > 0 && ldap_utf8_isspace(
392 &parts[count-1][len-1] ) )
398 parts[ count-1 ][ len ] = '\0';
402 * Don't forget to increment 'p' back to where
403 * it should be. If we don't, then we will
404 * never get past an "end quote."
409 rdn = *p ? &p[1] : p;
410 while ( ldap_utf8_isspace( rdn ) )
421 ldap_is_dns_dn( LDAP_CONST char *dn )
423 return dn[ 0 ] != '\0' && ldap_utf8_strpbrk( dn, "=,;" ) == NULL;