xref: /netbsd-src/external/bsd/openldap/dist/clients/tools/ldapurl.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
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
usage(void)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
do_uri_create(LDAPURLDesc * lud)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
do_uri_explode(const char * uri)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
main(int argc,char * argv[])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