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