]> git.sur5r.net Git - openldap/blob - libraries/libldap/getdn.c
2291a121db96942d0db505b24c19482f7ffdac34
[openldap] / libraries / libldap / getdn.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 /*  Portions
6  *  Copyright (c) 1994 Regents of the University of Michigan.
7  *  All rights reserved.
8  *
9  *  getdn.c
10  */
11
12 #include "portable.h"
13
14 #include <stdio.h>
15 #include <stdlib.h>
16
17 #include <ac/ctype.h>
18 #include <ac/socket.h>
19 #include <ac/string.h>
20 #include <ac/time.h>
21
22 #include "lber.h"
23 #include "ldap.h"
24 #include "ldap-int.h"
25
26 char *
27 ldap_get_dn( LDAP *ld, LDAPMessage *entry )
28 {
29         char            *dn;
30         BerElement      tmp;
31
32         Debug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
33
34         if ( entry == NULL ) {
35                 ld->ld_errno = LDAP_PARAM_ERROR;
36                 return( NULL );
37         }
38
39         tmp = *entry->lm_ber;   /* struct copy */
40         if ( ber_scanf( &tmp, "{a", &dn ) == LBER_ERROR ) {
41                 ld->ld_errno = LDAP_DECODING_ERROR;
42                 return( NULL );
43         }
44
45         return( dn );
46 }
47
48 char *
49 ldap_dn2ufn( char *dn )
50 {
51         char    *p, *ufn, *r;
52         int     state;
53
54         Debug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
55
56         if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL )
57                 return( ldap_strdup( dn ) );
58
59         ufn = ldap_strdup( ++p );
60
61 #define INQUOTE         1
62 #define OUTQUOTE        2
63         state = OUTQUOTE;
64         for ( p = ufn, r = ufn; *p; p++ ) {
65                 switch ( *p ) {
66                 case '\\':
67                         if ( *++p == '\0' )
68                                 p--;
69                         else {
70                                 *r++ = '\\';
71                                 *r++ = *p;
72                         }
73                         break;
74                 case '"':
75                         if ( state == INQUOTE )
76                                 state = OUTQUOTE;
77                         else
78                                 state = INQUOTE;
79                         *r++ = *p;
80                         break;
81                 case ';':
82                 case ',':
83                         if ( state == OUTQUOTE )
84                                 *r++ = ',';
85                         else
86                                 *r++ = *p;
87                         break;
88                 case '=':
89                         if ( state == INQUOTE )
90                                 *r++ = *p;
91                         else {
92                                 char    *rsave = r;
93
94                                 *r-- = '\0';
95                                 while ( !isspace( *r ) && *r != ';'
96                                     && *r != ',' && r > ufn )
97                                         r--;
98                                 r++;
99
100                                 if ( strcasecmp( r, "c" )
101                                     && strcasecmp( r, "o" )
102                                     && strcasecmp( r, "ou" )
103                                     && strcasecmp( r, "st" )
104                                     && strcasecmp( r, "l" )
105                                     && strcasecmp( r, "cn" ) ) {
106                                         r = rsave;
107                                         *r++ = '=';
108                                 }
109                         }
110                         break;
111                 default:
112                         *r++ = *p;
113                         break;
114                 }
115         }
116         *r = '\0';
117
118         return( ufn );
119 }
120
121 char **
122 ldap_explode_dns( char *dn )
123 {
124         int     ncomps, maxcomps;
125         char    *s;
126         char    **rdns;
127
128         if ( (rdns = (char **) malloc( 8 * sizeof(char *) )) == NULL ) {
129                 return( NULL );
130         }
131
132         maxcomps = 8;
133         ncomps = 0;
134         for ( s = strtok( dn, "@." ); s != NULL; s = strtok( NULL, "@." ) ) {
135                 if ( ncomps == maxcomps ) {
136                         maxcomps *= 2;
137                         if ( (rdns = (char **) realloc( rdns, maxcomps *
138                             sizeof(char *) )) == NULL ) {
139                                 return( NULL );
140                         }
141                 }
142                 rdns[ncomps++] = ldap_strdup( s );
143         }
144         rdns[ncomps] = NULL;
145
146         return( rdns );
147 }
148
149 char **
150 ldap_explode_dn( char *dn, int notypes )
151 {
152         char    *p, *q, *rdnstart, **rdns = NULL;
153         int     state, count = 0, endquote, len;
154
155         Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
156
157         if ( ldap_is_dns_dn( dn ) ) {
158                 return( ldap_explode_dns( dn ) );
159         }
160
161         rdnstart = dn;
162         p = dn-1;
163         state = OUTQUOTE;
164
165         do {
166
167                 ++p;
168                 switch ( *p ) {
169                 case '\\':
170                         if ( *++p == '\0' )
171                                 p--;
172                         break;
173                 case '"':
174                         if ( state == INQUOTE )
175                                 state = OUTQUOTE;
176                         else
177                                 state = INQUOTE;
178                         break;
179                 case ';':
180                 case ',':
181                 case '\0':
182                         if ( state == OUTQUOTE ) {
183                                 ++count;
184                                 if ( rdns == NULL ) {
185                                         if (( rdns = (char **)malloc( 8
186                                                  * sizeof( char *))) == NULL )
187                                                 return( NULL );
188                                 } else if ( count >= 8 ) {
189                                         if (( rdns = (char **)realloc( rdns,
190                                                 (count+1) * sizeof( char *)))
191                                                 == NULL )
192                                                 return( NULL );
193                                 }
194                                 rdns[ count ] = NULL;
195                                 endquote = 0;
196                                 if ( notypes ) {
197                                         for ( q = rdnstart;
198                                             q < p && *q != '='; ++q ) {
199                                                 ;
200                                         }
201                                         if ( q < p ) {
202                                                 rdnstart = ++q;
203                                         }
204                                         if ( *rdnstart == '"' ) {
205                                                 ++rdnstart;
206                                         }
207                                         
208                                         if ( *(p-1) == '"' ) {
209                                                 endquote = 1;
210                                                 --p;
211                                         }
212                                 }
213
214                                 len = p - rdnstart;
215                                 if (( rdns[ count-1 ] = (char *)calloc( 1,
216                                     len + 1 )) != NULL ) {
217                                         SAFEMEMCPY( rdns[ count-1 ], rdnstart,
218                                             len );
219                                         rdns[ count-1 ][ len ] = '\0';
220                                 }
221
222                                 /*
223                                  *  Don't forget to increment 'p' back to where
224                                  *  it should be.  If we don't, then we will
225                                  *  never get past an "end quote."
226                                  */
227                                 if ( endquote == 1 )
228                                         p++;
229
230                                 rdnstart = *p ? p + 1 : p;
231                                 while ( isspace( *rdnstart ))
232                                         ++rdnstart;
233                         }
234                         break;
235                 }
236         } while ( *p );
237
238         return( rdns );
239 }
240
241
242 int
243 ldap_is_dns_dn( char *dn )
244 {
245         return( dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL &&
246             strchr( dn, ',' ) == NULL );
247 }
248