1/* dntest.c -- OpenLDAP DN API Test Program */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 1998-2011 The OpenLDAP Foundation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
11 *
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
15 */
16/* ACKNOWLEDGEMENT:
17 * This program was initially developed by Pierangelo Masarati <ando@OpenLDAP.org>
18 * for inclusion in OpenLDAP Software.
19 */
20
21/*
22 * This program is designed to test the ldap_str2dn/ldap_dn2str
23 * functions
24 */
25#include "portable.h"
26
27#include <stdio.h>
28
29#include <ac/stdlib.h>
30#include <ac/string.h>
31#include <ac/unistd.h>
32
33#include <ldap.h>
34
35#include "ldap-int.h"
36
37#include "ldif.h"
38#include "lutil.h"
39#include "lutil_ldap.h"
40#include "ldap_defaults.h"
41
42int
43main( int argc, char *argv[] )
44{
45	int 		rc, i, debug = 0, f2 = 0;
46	unsigned 	flags[ 2 ] = { 0U, 0 };
47	char		*strin, *str = NULL, buf[ 1024 ];
48	LDAPDN		dn, dn2 = NULL;
49
50	while ( 1 ) {
51		int opt = getopt( argc, argv, "d:" );
52
53		if ( opt == EOF ) {
54			break;
55		}
56
57		switch ( opt ) {
58		case 'd':
59			debug = atoi( optarg );
60			break;
61		}
62	}
63
64	optind--;
65	argc -= optind;
66	argv += optind;
67
68	if ( argc < 2 ) {
69		fprintf( stderr, "usage: dntest <dn> [flags-in[,...]] [flags-out[,...]]\n\n" );
70		fprintf( stderr, "\tflags-in:   V3,V2,DCE,<flags>\n" );
71		fprintf( stderr, "\tflags-out:  V3,V2,UFN,DCE,AD,<flags>\n\n" );
72		fprintf( stderr, "\t<flags>: PRETTY,PEDANTIC,NOSPACES,NOONESPACE\n\n" );
73		return( 0 );
74	}
75
76	if ( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
77		fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
78	}
79	if ( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
80		fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
81	}
82
83	if ( strcmp( argv[ 1 ], "-" ) == 0 ) {
84		size_t len = fgets( buf, sizeof( buf ), stdin ) ? strlen( buf ) : 0;
85
86		if ( len == 0 || buf[ --len ] == '\n' ) {
87			buf[ len ] = '\0';
88		}
89		strin = buf;
90	} else {
91		strin = argv[ 1 ];
92	}
93
94	if ( argc >= 3 ) {
95		for ( i = 0; i < argc - 2; i++ ) {
96			char *s, *e;
97			for ( s = argv[ 2 + i ]; s; s = e ) {
98				e = strchr( s, ',' );
99				if ( e != NULL ) {
100					e[ 0 ] = '\0';
101					e++;
102				}
103
104				if ( !strcasecmp( s, "V3" ) ) {
105					flags[ i ] |= LDAP_DN_FORMAT_LDAPV3;
106				} else if ( !strcasecmp( s, "V2" ) ) {
107					flags[ i ] |= LDAP_DN_FORMAT_LDAPV2;
108				} else if ( !strcasecmp( s, "DCE" ) ) {
109					flags[ i ] |= LDAP_DN_FORMAT_DCE;
110				} else if ( !strcasecmp( s, "UFN" ) ) {
111					flags[ i ] |= LDAP_DN_FORMAT_UFN;
112				} else if ( !strcasecmp( s, "AD" ) ) {
113					flags[ i ] |= LDAP_DN_FORMAT_AD_CANONICAL;
114				} else if ( !strcasecmp( s, "PRETTY" ) ) {
115					flags[ i ] |= LDAP_DN_PRETTY;
116				} else if ( !strcasecmp( s, "PEDANTIC" ) ) {
117					flags[ i ] |= LDAP_DN_PEDANTIC;
118				} else if ( !strcasecmp( s, "NOSPACES" ) ) {
119					flags[ i ] |= LDAP_DN_P_NOLEADTRAILSPACES;
120				} else if ( !strcasecmp( s, "NOONESPACE" ) ) {
121					flags[ i ] |= LDAP_DN_P_NOSPACEAFTERRDN;
122				}
123			}
124		}
125	}
126
127	if ( flags[ 1 ] == 0 )
128		flags[ 1 ] = LDAP_DN_FORMAT_LDAPV3;
129
130	f2 = 1;
131
132	rc = ldap_str2dn( strin, &dn, flags[ 0 ] );
133
134	if ( rc == LDAP_SUCCESS ) {
135		int i;
136		if ( dn ) {
137			for ( i = 0; dn[ i ]; i++ ) {
138				LDAPRDN		rdn = dn[ i ];
139				char		*rstr = NULL;
140
141				if ( ldap_rdn2str( rdn, &rstr, flags[ f2 ] ) ) {
142					fprintf( stdout, "\tldap_rdn2str() failed\n" );
143					continue;
144				}
145
146				fprintf( stdout, "\tldap_rdn2str() = \"%s\"\n", rstr );
147				ldap_memfree( rstr );
148			}
149		} else {
150			fprintf( stdout, "\tempty DN\n" );
151		}
152	}
153
154	str = NULL;
155	if ( rc == LDAP_SUCCESS &&
156		ldap_dn2str( dn, &str, flags[ f2 ] ) == LDAP_SUCCESS )
157	{
158		char	**values, *tmp, *tmp2, *str2 = NULL;
159		int	n;
160
161		fprintf( stdout, "\nldap_dn2str(ldap_str2dn(\"%s\"))\n"
162				"\t= \"%s\"\n", strin, str );
163
164		switch ( flags[ f2 ] & LDAP_DN_FORMAT_MASK ) {
165		case LDAP_DN_FORMAT_UFN:
166		case LDAP_DN_FORMAT_AD_CANONICAL:
167			return( 0 );
168
169		case LDAP_DN_FORMAT_LDAPV3:
170		case LDAP_DN_FORMAT_LDAPV2:
171			n = ldap_dn2domain( strin, &tmp );
172			if ( n ) {
173				fprintf( stdout, "\nldap_dn2domain(\"%s\") FAILED\n", strin );
174			} else {
175				fprintf( stdout, "\nldap_dn2domain(\"%s\")\n"
176					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
177			}
178			ldap_memfree( tmp );
179
180			tmp = ldap_dn2ufn( strin );
181			fprintf( stdout, "\nldap_dn2ufn(\"%s\")\n"
182					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
183			ldap_memfree( tmp );
184
185			tmp = ldap_dn2dcedn( strin );
186			fprintf( stdout, "\nldap_dn2dcedn(\"%s\")\n"
187					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
188			tmp2 = ldap_dcedn2dn( tmp );
189			fprintf( stdout, "\nldap_dcedn2dn(\"%s\")\n"
190					"\t= \"%s\"\n",
191					tmp ? tmp : "", tmp2 ? tmp2 : "" );
192			ldap_memfree( tmp );
193			ldap_memfree( tmp2 );
194
195			tmp = ldap_dn2ad_canonical( strin );
196			fprintf( stdout, "\nldap_dn2ad_canonical(\"%s\")\n"
197					"\t= \"%s\"\n", strin, tmp ? tmp : "" );
198			ldap_memfree( tmp );
199
200			fprintf( stdout, "\nldap_explode_dn(\"%s\"):\n", str );
201			values = ldap_explode_dn( str, 0 );
202			for ( n = 0; values && values[ n ]; n++ ) {
203				char	**vv;
204				int	nn;
205
206				fprintf( stdout, "\t\"%s\"\n", values[ n ] );
207
208				fprintf( stdout, "\tldap_explode_rdn(\"%s\")\n",
209						values[ n ] );
210				vv = ldap_explode_rdn( values[ n ], 0 );
211				for ( nn = 0; vv && vv[ nn ]; nn++ ) {
212					fprintf( stdout, "\t\t'%s'\n",
213							vv[ nn ] );
214				}
215				LDAP_VFREE( vv );
216
217				fprintf( stdout, "\tldap_explode_rdn(\"%s\")"
218					       " (no types)\n", values[ n ] );
219				vv = ldap_explode_rdn( values[ n ], 1 );
220				for ( nn = 0; vv && vv[ nn ]; nn++ ) {
221					fprintf( stdout, "\t\t\t\"%s\"\n",
222							vv[ nn ] );
223				}
224				LDAP_VFREE( vv );
225
226			}
227			LDAP_VFREE( values );
228
229			fprintf( stdout, "\nldap_explode_dn(\"%s\")"
230					" (no types):\n", str );
231			values = ldap_explode_dn( str, 1 );
232			for ( n = 0; values && values[ n ]; n++ ) {
233				fprintf( stdout, "\t\"%s\"\n", values[ n ] );
234			}
235			LDAP_VFREE( values );
236
237			break;
238		}
239
240		dn2 = NULL;
241		rc = ldap_str2dn( str, &dn2, flags[ f2 ] );
242		str2 = NULL;
243		if ( rc == LDAP_SUCCESS &&
244				ldap_dn2str( dn2, &str2, flags[ f2 ] )
245				== LDAP_SUCCESS ) {
246			int 	iRDN;
247
248			fprintf( stdout, "\n\"%s\"\n\t == \"%s\" ? %s\n",
249				str, str2,
250				strcmp( str, str2 ) == 0 ? "yes" : "no" );
251
252			if( dn != NULL && dn2 == NULL ) {
253				fprintf( stdout, "dn mismatch\n" );
254			} else if (( dn != NULL ) && (dn2 != NULL))
255				for ( iRDN = 0; dn[ iRDN ] && dn2[ iRDN ]; iRDN++ )
256			{
257				LDAPRDN 	r = dn[ iRDN ];
258				LDAPRDN 	r2 = dn2[ iRDN ];
259				int 		iAVA;
260
261				for ( iAVA = 0; r[ iAVA ] && r2[ iAVA ]; iAVA++ ) {
262					LDAPAVA		*a = r[ iAVA ];
263					LDAPAVA		*a2 = r2[ iAVA ];
264
265					if ( a->la_attr.bv_len != a2->la_attr.bv_len ) {
266						fprintf( stdout, "ava(%d), rdn(%d) attr len mismatch (%ld->%ld)\n",
267								iAVA + 1, iRDN + 1,
268								a->la_attr.bv_len, a2->la_attr.bv_len );
269					} else if ( memcmp( a->la_attr.bv_val, a2->la_attr.bv_val, a->la_attr.bv_len ) ) {
270						fprintf( stdout, "ava(%d), rdn(%d) attr mismatch\n",
271								iAVA + 1, iRDN + 1 );
272					} else if ( a->la_flags != a2->la_flags ) {
273						fprintf( stdout, "ava(%d), rdn(%d) flag mismatch (%x->%x)\n",
274								iAVA + 1, iRDN + 1, a->la_flags, a2->la_flags );
275					} else if ( a->la_value.bv_len != a2->la_value.bv_len ) {
276						fprintf( stdout, "ava(%d), rdn(%d) value len mismatch (%ld->%ld)\n",
277								iAVA + 1, iRDN + 1,
278								a->la_value.bv_len, a2->la_value.bv_len );
279					} else if ( memcmp( a->la_value.bv_val, a2->la_value.bv_val, a->la_value.bv_len ) ) {
280						fprintf( stdout, "ava(%d), rdn(%d) value mismatch\n",
281								iAVA + 1, iRDN + 1 );
282					}
283				}
284			}
285
286			ldap_dnfree( dn2 );
287			ldap_memfree( str2 );
288		}
289		ldap_memfree( str );
290	}
291	ldap_dnfree( dn );
292
293	/* note: dn is not freed */
294
295	return( 0 );
296}
297