2 * Copyright (c) 2001 by Sun Microsystems, Inc.
6 #pragma ident "%Z%%M% %I% %E% SMI"
9 * The contents of this file are subject to the Netscape Public
10 * License Version 1.1 (the "License"); you may not use this file
11 * except in compliance with the License. You may obtain a copy of
12 * the License at http://www.mozilla.org/NPL/
14 * Software distributed under the License is distributed on an "AS
15 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
16 * implied. See the License for the specific language governing
17 * rights and limitations under the License.
19 * The Original Code is Mozilla Communicator client code, released
22 * The Initial Developer of the Original Code is Netscape
23 * Communications Corporation. Portions created by Netscape are
24 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
30 * Copyright (c) 1994 Regents of the University of Michigan.
31 * All rights reserved.
39 static char copyright
[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
47 ldap_get_dn( LDAP
*ld
, LDAPMessage
*entry
)
50 struct berelement tmp
;
52 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_get_dn\n", 0, 0, 0 );
54 if ( !NSLDAPI_VALID_LDAP_POINTER( ld
)) {
55 return( NULL
); /* punt */
58 if ( !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry
)) {
59 LDAP_SET_LDERRNO( ld
, LDAP_PARAM_ERROR
, NULL
, NULL
);
63 tmp
= *entry
->lm_ber
; /* struct copy */
64 if ( ber_scanf( &tmp
, "{a", &dn
) == LBER_ERROR
) {
65 LDAP_SET_LDERRNO( ld
, LDAP_DECODING_ERROR
, NULL
, NULL
);
74 ldap_dn2ufn( const char *dn
)
80 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_dn2ufn\n", 0, 0, 0 );
86 if ( ldap_is_dns_dn( dn
) || ( p
= strchr( dn
, '=' )) == NULL
)
87 return( nsldapi_strdup( (char *)dn
));
89 ufn
= nsldapi_strdup( ++p
);
94 for ( p
= ufn
, r
= ufn
; *p
; p
+= plen
) {
102 r
+= (plen
= LDAP_UTF8COPY(r
,p
));
106 if ( state
== INQUOTE
)
114 if ( state
== OUTQUOTE
)
120 if ( state
== INQUOTE
)
126 while ( !ldap_utf8isspace( r
) && *r
!= ';'
127 && *r
!= ',' && r
> ufn
)
131 if ( strcasecmp( r
, "c" )
132 && strcasecmp( r
, "o" )
133 && strcasecmp( r
, "ou" )
134 && strcasecmp( r
, "st" )
135 && strcasecmp( r
, "l" )
136 && strcasecmp( r
, "dc" )
137 && strcasecmp( r
, "uid" )
138 && strcasecmp( r
, "cn" ) ) {
145 r
+= (plen
= LDAP_UTF8COPY(r
,p
));
156 ldap_explode_dns( const char *dn
)
158 int ncomps
, maxcomps
;
161 #ifdef HAVE_STRTOK_R /* defined in portable.h */
169 if ( (rdns
= (char **)NSLDAPI_MALLOC( 8 * sizeof(char *) )) == NULL
) {
175 cpydn
= nsldapi_strdup( (char *)dn
);
176 for ( s
= STRTOK( cpydn
, "@.", &lasts
); s
!= NULL
;
177 s
= STRTOK( NULL
, "@.", &lasts
) ) {
178 if ( ncomps
== maxcomps
) {
180 if ( (rdns
= (char **)NSLDAPI_REALLOC( rdns
, maxcomps
*
181 sizeof(char *) )) == NULL
) {
182 NSLDAPI_FREE( cpydn
);
186 rdns
[ncomps
++] = nsldapi_strdup( s
);
189 NSLDAPI_FREE( cpydn
);
198 ldap_explode( const char *dn
, const int notypes
, const int nametype
)
200 char *p
, *q
, *rdnstart
, **rdns
= NULL
;
202 int state
, count
= 0, endquote
, len
, goteq
;
204 LDAPDebug( LDAP_DEBUG_TRACE
, "ldap_explode\n", 0, 0, 0 );
211 if ( ldap_is_dns_dn( dn
) ) {
212 return( ldap_explode_dns( dn
) );
216 while ( ldap_utf8isspace( (char *)dn
)) { /* ignore leading spaces */
220 p
= rdnstart
= (char *) dn
;
232 plen
= LDAP_UTF8LEN(p
);
235 if ( state
== INQUOTE
)
240 case '+': if ( nametype
!= LDAP_RDN
) break;
244 if ( state
== OUTQUOTE
) {
246 * semicolon and comma are not valid RDN
249 if ( nametype
== LDAP_RDN
&&
250 ( *p
== ';' || *p
== ',' || !goteq
)) {
251 ldap_charray_free( rdns
);
254 if ( (*p
== ',' || *p
== ';') && !goteq
) {
255 /* If we get here, we have a case similar
256 * to <attr>=<value>,<string>,<attr>=<value>
257 * This is not a valid dn */
258 ldap_charray_free( rdns
);
263 if ( rdns
== NULL
) {
264 if (( rdns
= (char **)NSLDAPI_MALLOC( 8
265 * sizeof( char *))) == NULL
)
267 } else if ( count
>= 8 ) {
268 if (( rdns
= (char **)NSLDAPI_REALLOC(
270 sizeof( char *))) == NULL
)
273 rdns
[ count
] = NULL
;
277 q
< p
&& *q
!= '='; ++q
) {
280 if ( q
< p
) { /* *q == '=' */
283 if ( *rdnstart
== '"' ) {
287 if ( *(p
-1) == '"' ) {
294 if (( rdns
[ count
-1 ] = (char *)NSLDAPI_CALLOC(
295 1, len
+ 1 )) != NULL
) {
296 SAFEMEMCPY( rdns
[ count
-1 ], rdnstart
,
299 /* trim trailing spaces */
302 &rdns
[count
-1][len
-1] )) {
306 rdns
[ count
-1 ][ len
] = '\0';
310 * Don't forget to increment 'p' back to where
311 * it should be. If we don't, then we will
312 * never get past an "end quote."
317 rdnstart
= *p
? p
+ 1 : p
;
318 while ( ldap_utf8isspace( rdnstart
))
323 if ( state
== OUTQUOTE
) {
328 plen
= LDAP_UTF8LEN(p
);
338 ldap_explode_dn( const char *dn
, const int notypes
)
340 return( ldap_explode( dn
, notypes
, LDAP_DN
) );
345 ldap_explode_rdn( const char *rdn
, const int notypes
)
347 return( ldap_explode( rdn
, notypes
, LDAP_RDN
) );
352 ldap_is_dns_dn( const char *dn
)
354 return( dn
!= NULL
&& dn
[ 0 ] != '\0' && strchr( dn
, '=' ) == NULL
&&
355 strchr( dn
, ',' ) == NULL
);
361 * Convert a DNS domain name into an X.500 distinguished name.
362 * For example, "sales.wiz.com" -> "dc=sales,dc=wiz,dc=com"
364 * If an error is encountered zero is returned, otherwise a string
365 * distinguished name and the number of nameparts is returned.
366 * The caller should free the returned string if it is non-zero.
379 /* check for NULL string, empty name and name ending in '.' */
380 if (dns_name
&& (dns_len
= strlen(dns_name
)) &&
381 (dns_name
[dns_len
- 1] != '.')) {
382 if (dn
= (char *)malloc(dns_len
* 3 + 1)) {
390 while (*dns_name
&& (*dns_name
!= '.')) {
393 if (*dns_name
== '.') {