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