]> git.sur5r.net Git - openldap/blob - libraries/libldap/getdn.c
Cast char* argument to hh_to_c() to Byte*
[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 "ldap-int.h"
23
24 static char **explode_name( char *name, int notypes, int is_dn );
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( strdup( dn ) );
58
59         ufn = 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( (unsigned char) *r )
96                                         && *r != ';' && *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         char    *tok_r;
128
129         if ( (rdns = (char **) malloc( 8 * sizeof(char *) )) == NULL ) {
130                 return( NULL );
131         }
132
133         maxcomps = 8;
134         ncomps = 0;
135         for ( s = ldap_pvt_strtok( dn, "@.", &tok_r ); s != NULL; 
136               s = ldap_pvt_strtok( NULL, "@.", &tok_r ) ) {
137                 if ( ncomps == maxcomps ) {
138                         maxcomps *= 2;
139                         if ( (rdns = (char **) realloc( rdns, maxcomps *
140                             sizeof(char *) )) == NULL ) {
141                                 return( NULL );
142                         }
143                 }
144                 rdns[ncomps++] = strdup( s );
145         }
146         rdns[ncomps] = NULL;
147
148         return( rdns );
149 }
150
151 char **
152 ldap_explode_dn( char *dn, int notypes )
153 {
154         Debug( LDAP_DEBUG_TRACE, "ldap_explode_dn\n", 0, 0, 0 );
155
156         if ( ldap_is_dns_dn( dn ) ) {
157                 return( ldap_explode_dns( dn ) );
158         }
159         return explode_name( dn, notypes, 1 );
160 }
161
162 char **
163 ldap_explode_rdn( char *rdn, int notypes )
164 {
165         Debug( LDAP_DEBUG_TRACE, "ldap_explode_rdn\n", 0, 0, 0 );
166         return explode_name( rdn, notypes, 0 );
167 }
168
169 static char **
170 explode_name( char *name, int notypes, int is_dn )
171 {
172         char    *p, *q, **parts = NULL;
173         int     state, count = 0, endquote, len;
174
175         p = name-1;
176         state = OUTQUOTE;
177
178         do {
179
180                 ++p;
181                 switch ( *p ) {
182                 case '\\':
183                         if ( *++p == '\0' )
184                                 p--;
185                         break;
186                 case '"':
187                         if ( state == INQUOTE )
188                                 state = OUTQUOTE;
189                         else
190                                 state = INQUOTE;
191                         break;
192                 case '+':
193                         if (!is_dn)
194                                 goto end_part;
195                         break;
196                 case ';':
197                 case ',':
198                         if (!is_dn)
199                                 break;
200                         goto end_part;
201                 case '\0':
202                 end_part:
203                         if ( state == OUTQUOTE ) {
204                                 ++count;
205                                 if ( parts == NULL ) {
206                                         if (( parts = (char **)malloc( 8
207                                                  * sizeof( char *))) == NULL )
208                                                 return( NULL );
209                                 } else if ( count >= 8 ) {
210                                         if (( parts = (char **)realloc( parts,
211                                                 (count+1) * sizeof( char *)))
212                                                 == NULL )
213                                                 return( NULL );
214                                 }
215                                 parts[ count ] = NULL;
216                                 endquote = 0;
217                                 if ( notypes ) {
218                                         for ( q = name;
219                                             q < p && *q != '='; ++q ) {
220                                                 ;
221                                         }
222                                         if ( q < p ) {
223                                                 name = ++q;
224                                         }
225                                         if ( *name == '"' ) {
226                                                 ++name;
227                                         }
228                                         
229                                         if ( *(p-1) == '"' ) {
230                                                 endquote = 1;
231                                                 --p;
232                                         }
233                                 }
234
235                                 len = p - name;
236                                 if (( parts[ count-1 ] = (char *)calloc( 1,
237                                     len + 1 )) != NULL ) {
238                                         SAFEMEMCPY( parts[ count-1 ], name,
239                                             len );
240                                         parts[ count-1 ][ len ] = '\0';
241                                 }
242
243                                 /*
244                                  *  Don't forget to increment 'p' back to where
245                                  *  it should be.  If we don't, then we will
246                                  *  never get past an "end quote."
247                                  */
248                                 if ( endquote == 1 )
249                                         p++;
250
251                                 name = *p ? p + 1 : p;
252                                 while ( isascii( *name ) && isspace( *name ) )
253                                         ++name;
254                         }
255                         break;
256                 }
257         } while ( *p );
258
259         return( parts );
260 }
261
262
263 int
264 ldap_is_dns_dn( char *dn )
265 {
266         return( dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL &&
267             strchr( dn, ',' ) == NULL );
268 }
269