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 DN_TYPE_LDAP_RDN 0
27 #define DN_TYPE_LDAP_DN 1
28 #define DN_TYPE_DCE_DN 2
30 static char **explode_name( const char *name, int notypes, int is_dn );
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 = strchr( dn, '=' ) ) == NULL )
69 return( LDAP_STRDUP( dn ) );
73 ufn = LDAP_STRDUP( ++p );
78 for ( p = ufn, r = ufn; *p; p++ ) {
89 if ( state == INQUOTE )
97 if ( state == OUTQUOTE )
103 if ( state == INQUOTE )
109 while ( !isspace( (unsigned char) *r )
110 && *r != ';' && *r != ',' && r > ufn )
114 if ( strcasecmp( r, "c" )
115 && strcasecmp( r, "o" )
116 && strcasecmp( r, "ou" )
117 && strcasecmp( r, "st" )
118 && strcasecmp( r, "l" )
119 && strcasecmp( r, "cn" ) ) {
136 ldap_explode_dns( LDAP_CONST char *dn_in )
146 if ( (dn = LDAP_STRDUP( dn_in )) == NULL ) {
150 if ( (rdns = (char **) LDAP_MALLOC( maxcomps * sizeof(char *) )) == NULL ) {
156 for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL;
157 s = ldap_pvt_strtok( NULL, "@.", &tok_r ) )
159 if ( ncomps == maxcomps ) {
161 if ( (rdns = (char **) LDAP_REALLOC( rdns, maxcomps *
162 sizeof(char *) )) == NULL )
168 rdns[ncomps++] = LDAP_STRDUP( s );
175 rdns = (char **) LDAP_REALLOC( rdns, (ncomps+1) * sizeof(char*) );
180 ldap_explode_dn( LDAP_CONST char *dn, int notypes )
182 Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
184 if ( ldap_is_dns_dn( dn ) ) {
185 return( ldap_explode_dns( dn ) );
187 return explode_name( dn, notypes, DN_TYPE_LDAP_DN );
191 ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
193 Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
194 return explode_name( rdn, notypes, DN_TYPE_LDAP_RDN );
198 ldap_dn2dcedn( LDAP_CONST char *dn )
200 char *dce, *q, **rdns, **p;
203 Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
205 rdns = explode_name( dn, 0, DN_TYPE_LDAP_DN );
206 if ( rdns == NULL ) {
210 for ( p = rdns; *p != NULL; p++ ) {
211 len += strlen( *p ) + 1;
214 q = dce = LDAP_MALLOC( len + 1 );
219 p--; /* get back past NULL */
221 for ( ; p != rdns; p-- ) {
236 ldap_dcedn2dn( LDAP_CONST char *dce )
238 char *dn, *q, **rdns, **p;
241 Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
243 rdns = explode_name( dce, 0, DN_TYPE_DCE_DN );
244 if ( rdns == NULL ) {
250 for ( p = rdns; *p != NULL; p++ ) {
251 len += strlen( *p ) + 1;
254 q = dn = LDAP_MALLOC( len );
261 for ( ; p != rdns; p-- ) {
269 /* the name was fully qualified, thus the most-significant
270 * RDN was empty. trash the last comma */
274 /* the name was relative. copy the most significant RDN */
282 explode_name( const char *name, int notypes, int is_dn )
286 int state, count = 0, endquote, len;
300 if ( state == INQUOTE )
306 if (is_dn == DN_TYPE_LDAP_RDN)
310 if (is_dn == DN_TYPE_DCE_DN)
315 if (is_dn == DN_TYPE_LDAP_DN)
320 if ( state == OUTQUOTE ) {
322 if ( parts == NULL ) {
323 if (( parts = (char **)LDAP_MALLOC( 8
324 * sizeof( char *))) == NULL )
326 } else if ( count >= 8 ) {
327 if (( parts = (char **)LDAP_REALLOC( parts,
328 (count+1) * sizeof( char *)))
332 parts[ count ] = NULL;
336 q < p && *q != '='; ++q ) {
342 if ( *name == '"' ) {
346 if ( *(p-1) == '"' ) {
353 if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
354 len + 1 )) != NULL ) {
355 SAFEMEMCPY( parts[ count-1 ], name,
357 parts[ count-1 ][ len ] = '\0';
361 * Don't forget to increment 'p' back to where
362 * it should be. If we don't, then we will
363 * never get past an "end quote."
368 name = *p ? p + 1 : p;
369 while ( isascii( *name ) && isspace( *name ) )
381 ldap_is_dns_dn( LDAP_CONST char *dn )
383 return( dn[ 0 ] != '\0'
384 && strchr( dn, '=' ) == NULL
385 && strchr( dn, ',' ) == NULL
386 && strchr( dn, ';' ) == NULL );