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