3 * Copyright 1998-2000 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 )
61 Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
63 /* produces completely untyped UFNs */
69 vals = ldap_explode_dn( dn , 0 );
74 for ( i = 0; vals[i]; i++ ) {
77 rvals = ldap_explode_rdn( vals[i] , 1 );
78 if ( rvals == NULL ) {
84 vals[i] = ldap_charray2str( rvals, " + " );
88 ufn = ldap_charray2str( vals, ", " );
95 ldap_explode_dn( LDAP_CONST char *dn, int notypes )
97 Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
99 return explode_name( dn, notypes, NAME_TYPE_LDAP_DN );
103 ldap_explode_rdn( LDAP_CONST char *rdn, int notypes )
105 Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
106 return explode_name( rdn, notypes, NAME_TYPE_LDAP_RDN );
110 ldap_dn2dcedn( LDAP_CONST char *dn )
112 char *dce, *q, **rdns, **p;
115 Debug( LDAP_DEBUG_TRACE, "ldap_dn2dcedn\n", 0, 0, 0 );
117 rdns = explode_name( dn, 0, NAME_TYPE_LDAP_DN );
118 if ( rdns == NULL ) {
122 for ( p = rdns; *p != NULL; p++ ) {
123 len += strlen( *p ) + 1;
126 q = dce = LDAP_MALLOC( len + 1 );
131 p--; /* get back past NULL */
133 for ( ; p != rdns; p-- ) {
148 ldap_dcedn2dn( LDAP_CONST char *dce )
150 char *dn, *q, **rdns, **p;
153 Debug( LDAP_DEBUG_TRACE, "ldap_dcedn2dn\n", 0, 0, 0 );
155 rdns = explode_name( dce, 0, NAME_TYPE_DCE_DN );
156 if ( rdns == NULL ) {
162 for ( p = rdns; *p != NULL; p++ ) {
163 len += strlen( *p ) + 1;
166 q = dn = LDAP_MALLOC( len );
173 for ( ; p != rdns; p-- ) {
181 /* the name was fully qualified, thus the most-significant
182 * RDN was empty. trash the last comma */
186 /* the name was relative. copy the most significant RDN */
197 explode_name( const char *name, int notypes, int is_type )
199 const char *p, *q, *rdn;
201 int offset, state, have_equals, count = 0, endquote, len;
204 if(name == NULL) name = "";
206 /* skip leading whitespace */
207 while( ldap_utf8_isspace( name )) {
208 LDAP_UTF8_INCR( name );
223 if ( p[1] != '\0' ) {
224 offset = LDAP_UTF8_OFFSET(++p);
228 if ( state == INQUOTE )
234 if( state == OUTQUOTE ) have_equals++;
237 if (is_type == NAME_TYPE_LDAP_RDN)
241 if (is_type == NAME_TYPE_DCE_DN)
246 if (is_type == NAME_TYPE_LDAP_DN)
251 if ( state == OUTQUOTE ) {
255 if ( parts == NULL ) {
256 if (( parts = (char **)LDAP_MALLOC( 8
257 * sizeof( char *))) == NULL )
259 } else if ( count >= 8 ) {
260 if (( parts = (char **)LDAP_REALLOC( parts,
261 (count+1) * sizeof( char *)))
266 parts[ count ] = NULL;
270 for ( q = rdn; q < p && *q != '='; ++q ) {
282 if ( p[-1] == '"' ) {
290 if (( parts[ count-1 ] = (char *)LDAP_CALLOC( 1,
293 AC_MEMCPY( parts[ count-1 ], rdn, len );
296 /* skip trailing spaces */
297 while( len > 0 && ldap_utf8_isspace(
298 &parts[count-1][len-1] ) )
304 parts[ count-1 ][ len ] = '\0';
308 * Don't forget to increment 'p' back to where
309 * it should be. If we don't, then we will
310 * never get past an "end quote."
315 rdn = *p ? &p[1] : p;
316 while ( ldap_utf8_isspace( rdn ) )