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