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