1/* ldapurl -- a tool for generating LDAP URLs */ 2/* $OpenLDAP$ */ 3/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 4 * 5 * Copyright 2008-2011 The OpenLDAP Foundation. 6 * Portions Copyright 2008 Pierangelo Masarati, SysNet 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted only as authorized by the OpenLDAP 11 * Public License. 12 * 13 * A copy of this license is available in the file LICENSE in the 14 * top-level directory of the distribution or, alternatively, at 15 * <http://www.OpenLDAP.org/license.html>. 16 */ 17/* Portions Copyright (c) 1992-1996 Regents of the University of Michigan. 18 * All rights reserved. 19 * 20 * Redistribution and use in source and binary forms are permitted 21 * provided that this notice is preserved and that due credit is given 22 * to the University of Michigan at Ann Arbor. The name of the 23 * University may not be used to endorse or promote products derived 24 * from this software without specific prior written permission. This 25 * software is provided ``as is'' without express or implied warranty. 26 */ 27/* ACKNOWLEDGEMENTS: 28 * This work was originally developed by Pierangelo Masarati 29 * for inclusion in OpenLDAP software. 30 */ 31 32#include "portable.h" 33 34#include <ac/stdlib.h> 35#include <stdio.h> 36#include <ac/unistd.h> 37 38#include "ldap.h" 39#include "ldap_pvt.h" 40#include "lutil.h" 41 42static int 43usage(void) 44{ 45 fprintf( stderr, _("usage: %s [options]\n\n"), "ldapurl" ); 46 fprintf( stderr, _("generates RFC 4516 LDAP URL with extensions\n\n" ) ); 47 fprintf( stderr, _("URL options:\n")); 48 fprintf( stderr, _(" -a attrs comma separated list of attributes\n" ) ); 49 fprintf( stderr, _(" -b base (RFC 4514 LDAP DN)\n" ) ); 50 fprintf( stderr, _(" -E ext (format: \"ext=value\"; multiple occurrences allowed)\n" ) ); 51 fprintf( stderr, _(" -f filter (RFC 4515 LDAP filter)\n" ) ); 52 fprintf( stderr, _(" -h host \n" ) ); 53 fprintf( stderr, _(" -p port (default: 389 for ldap, 636 for ldaps)\n" ) ); 54 fprintf( stderr, _(" -s scope (RFC 4511 searchScope and extensions)\n" ) ); 55 fprintf( stderr, _(" -S scheme (RFC 4516 LDAP URL scheme and extensions)\n" ) ); 56 exit( EXIT_FAILURE ); 57} 58 59static int 60do_uri_create( LDAPURLDesc *lud ) 61{ 62 char *uri; 63 64 if ( lud->lud_scheme == NULL ) { 65 lud->lud_scheme = "ldap"; 66 } 67 68 if ( lud->lud_port == -1 ) { 69 if ( strcasecmp( lud->lud_scheme, "ldap" ) == 0 ) { 70 lud->lud_port = LDAP_PORT; 71 72 } else if ( strcasecmp( lud->lud_scheme, "ldaps" ) == 0 ) { 73 lud->lud_port = LDAPS_PORT; 74 75 } else if ( strcasecmp( lud->lud_scheme, "ldapi" ) == 0 ) { 76 lud->lud_port = 0; 77 78 } else { 79 /* forgiving... */ 80 lud->lud_port = 0; 81 } 82 } 83 84 if ( lud->lud_scope == -1 ) { 85 lud->lud_scope = LDAP_SCOPE_DEFAULT; 86 } 87 88 uri = ldap_url_desc2str( lud ); 89 90 if ( lud->lud_attrs != NULL ) { 91 ldap_charray_free( lud->lud_attrs ); 92 lud->lud_attrs = NULL; 93 } 94 95 if ( lud->lud_exts != NULL ) { 96 free( lud->lud_exts ); 97 lud->lud_exts = NULL; 98 } 99 100 if ( uri == NULL ) { 101 fprintf( stderr, "unable to generate URI\n" ); 102 exit( EXIT_FAILURE ); 103 } 104 105 printf( "%s\n", uri ); 106 free( uri ); 107 108 return 0; 109} 110 111static int 112do_uri_explode( const char *uri ) 113{ 114 LDAPURLDesc *lud; 115 int rc; 116 117 rc = ldap_url_parse( uri, &lud ); 118 if ( rc != LDAP_URL_SUCCESS ) { 119 fprintf( stderr, "unable to parse URI \"%s\"\n", uri ); 120 return 1; 121 } 122 123 if ( lud->lud_scheme != NULL && lud->lud_scheme[0] != '\0' ) { 124 printf( "scheme: %s\n", lud->lud_scheme ); 125 } 126 127 if ( lud->lud_host != NULL && lud->lud_host[0] != '\0' ) { 128 printf( "host: %s\n", lud->lud_host ); 129 } 130 131 if ( lud->lud_port != 0 ) { 132 printf( "port: %d\n", lud->lud_port ); 133 } 134 135 if ( lud->lud_dn != NULL && lud->lud_dn[0] != '\0' ) { 136 printf( "dn: %s\n", lud->lud_dn ); 137 } 138 139 if ( lud->lud_attrs != NULL ) { 140 int i; 141 142 for ( i = 0; lud->lud_attrs[i] != NULL; i++ ) { 143 printf( "selector: %s\n", lud->lud_attrs[i] ); 144 } 145 } 146 147 if ( lud->lud_scope != LDAP_SCOPE_DEFAULT ) { 148 printf( "scope: %s\n", ldap_pvt_scope2str( lud->lud_scope ) ); 149 } 150 151 if ( lud->lud_filter != NULL && lud->lud_filter[0] != '\0' ) { 152 printf( "filter: %s\n", lud->lud_filter ); 153 } 154 155 if ( lud->lud_exts != NULL ) { 156 int i; 157 158 for ( i = 0; lud->lud_exts[i] != NULL; i++ ) { 159 printf( "extension: %s\n", lud->lud_exts[i] ); 160 } 161 } 162 163 return 0; 164} 165 166int 167main( int argc, char *argv[]) 168{ 169 LDAPURLDesc lud = { 0 }; 170 char *uri = NULL; 171 int gotlud = 0; 172 int nexts = 0; 173 174 lud.lud_port = -1; 175 lud.lud_scope = -1; 176 177 while ( 1 ) { 178 int opt = getopt( argc, argv, "S:h:p:b:a:s:f:E:H:" ); 179 180 if ( opt == EOF ) { 181 break; 182 } 183 184 if ( opt == 'H' ) { 185 if ( gotlud ) { 186 fprintf( stderr, "option -H incompatible with previous options\n" ); 187 usage(); 188 } 189 190 if ( uri != NULL ) { 191 fprintf( stderr, "URI already provided\n" ); 192 usage(); 193 } 194 195 uri = optarg; 196 continue; 197 } 198 199 switch ( opt ) { 200 case 'S': 201 case 'h': 202 case 'p': 203 case 'b': 204 case 'a': 205 case 's': 206 case 'f': 207 case 'E': 208 if ( uri != NULL ) { 209 fprintf( stderr, "option -%c incompatible with -H\n", opt ); 210 usage(); 211 } 212 gotlud++; 213 } 214 215 switch ( opt ) { 216 case 'S': 217 if ( lud.lud_scheme != NULL ) { 218 fprintf( stderr, "scheme already provided\n" ); 219 usage(); 220 } 221 lud.lud_scheme = optarg; 222 break; 223 224 case 'h': 225 if ( lud.lud_host != NULL ) { 226 fprintf( stderr, "host already provided\n" ); 227 usage(); 228 } 229 lud.lud_host = optarg; 230 break; 231 232 case 'p': 233 if ( lud.lud_port != -1 ) { 234 fprintf( stderr, "port already provided\n" ); 235 usage(); 236 } 237 238 if ( lutil_atoi( &lud.lud_port, optarg ) ) { 239 fprintf( stderr, "unable to parse port \"%s\"\n", optarg ); 240 usage(); 241 } 242 break; 243 244 case 'b': 245 if ( lud.lud_dn != NULL ) { 246 fprintf( stderr, "base already provided\n" ); 247 usage(); 248 } 249 lud.lud_dn = optarg; 250 break; 251 252 case 'a': 253 if ( lud.lud_attrs != NULL ) { 254 fprintf( stderr, "attrs already provided\n" ); 255 usage(); 256 } 257 lud.lud_attrs = ldap_str2charray( optarg, "," ); 258 if ( lud.lud_attrs == NULL ) { 259 fprintf( stderr, "unable to parse attrs list \"%s\"\n", optarg ); 260 usage(); 261 } 262 break; 263 264 case 's': 265 if ( lud.lud_scope != -1 ) { 266 fprintf( stderr, "scope already provided\n" ); 267 usage(); 268 } 269 270 lud.lud_scope = ldap_pvt_str2scope( optarg ); 271 if ( lud.lud_scope == -1 ) { 272 fprintf( stderr, "unable to parse scope \"%s\"\n", optarg ); 273 usage(); 274 } 275 break; 276 277 case 'f': 278 if ( lud.lud_filter != NULL ) { 279 fprintf( stderr, "filter already provided\n" ); 280 usage(); 281 } 282 lud.lud_filter = optarg; 283 break; 284 285 case 'E': 286 lud.lud_exts = (char **)realloc( lud.lud_exts, 287 sizeof( char * ) * ( nexts + 2 ) ); 288 lud.lud_exts[ nexts++ ] = optarg; 289 lud.lud_exts[ nexts ] = NULL; 290 break; 291 292 default: 293 assert( opt != 'H' ); 294 usage(); 295 } 296 } 297 298 if ( uri != NULL ) { 299 return do_uri_explode( uri ); 300 301 } 302 303 return do_uri_create( &lud ); 304} 305