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-2021 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 #include <ac/socket.h>
38
39 #include "ldap.h"
40 #include "ldap_pvt.h"
41 #include "lutil.h"
42
43 static int
usage(void)44 usage(void)
45 {
46 fprintf( stderr, _("usage: %s [options]\n\n"), "ldapurl" );
47 fprintf( stderr, _("generates RFC 4516 LDAP URL with extensions\n\n" ) );
48 fprintf( stderr, _("URL options:\n"));
49 fprintf( stderr, _(" -a attrs comma separated list of attributes\n" ) );
50 fprintf( stderr, _(" -b base (RFC 4514 LDAP DN)\n" ) );
51 fprintf( stderr, _(" -E ext (format: \"ext=value\"; multiple occurrences allowed)\n" ) );
52 fprintf( stderr, _(" -f filter (RFC 4515 LDAP filter)\n" ) );
53 fprintf( stderr, _(" -h host \n" ) );
54 fprintf( stderr, _(" -p port (default: 389 for ldap, 636 for ldaps)\n" ) );
55 fprintf( stderr, _(" -s scope (RFC 4511 searchScope and extensions)\n" ) );
56 fprintf( stderr, _(" -S scheme (RFC 4516 LDAP URL scheme and extensions)\n" ) );
57 exit( EXIT_FAILURE );
58 }
59
60 static int
do_uri_create(LDAPURLDesc * lud)61 do_uri_create( LDAPURLDesc *lud )
62 {
63 char *uri;
64
65 if ( lud->lud_scheme == NULL ) {
66 lud->lud_scheme = "ldap";
67 }
68
69 if ( lud->lud_port == -1 ) {
70 if ( strcasecmp( lud->lud_scheme, "ldap" ) == 0 ) {
71 lud->lud_port = LDAP_PORT;
72
73 } else if ( strcasecmp( lud->lud_scheme, "ldaps" ) == 0 ) {
74 lud->lud_port = LDAPS_PORT;
75
76 } else if ( strcasecmp( lud->lud_scheme, "ldapi" ) == 0 ) {
77 lud->lud_port = 0;
78
79 } else {
80 /* forgiving... */
81 lud->lud_port = 0;
82 }
83 }
84
85 if ( lud->lud_scope == -1 ) {
86 lud->lud_scope = LDAP_SCOPE_DEFAULT;
87 }
88
89 uri = ldap_url_desc2str( lud );
90
91 if ( lud->lud_attrs != NULL ) {
92 ldap_charray_free( lud->lud_attrs );
93 lud->lud_attrs = NULL;
94 }
95
96 if ( lud->lud_exts != NULL ) {
97 free( lud->lud_exts );
98 lud->lud_exts = NULL;
99 }
100
101 if ( uri == NULL ) {
102 fprintf( stderr, "unable to generate URI\n" );
103 exit( EXIT_FAILURE );
104 }
105
106 printf( "%s\n", uri );
107 free( uri );
108
109 return 0;
110 }
111
112 static int
do_uri_explode(const char * uri)113 do_uri_explode( const char *uri )
114 {
115 LDAPURLDesc *lud;
116 int rc;
117
118 rc = ldap_url_parse( uri, &lud );
119 if ( rc != LDAP_URL_SUCCESS ) {
120 fprintf( stderr, "unable to parse URI \"%s\"\n", uri );
121 return 1;
122 }
123
124 if ( lud->lud_scheme != NULL && lud->lud_scheme[0] != '\0' ) {
125 printf( "scheme: %s\n", lud->lud_scheme );
126 }
127
128 if ( lud->lud_host != NULL && lud->lud_host[0] != '\0' ) {
129 printf( "host: %s\n", lud->lud_host );
130 }
131
132 if ( lud->lud_port != 0 ) {
133 printf( "port: %d\n", lud->lud_port );
134 }
135
136 if ( lud->lud_dn != NULL && lud->lud_dn[0] != '\0' ) {
137 printf( "dn: %s\n", lud->lud_dn );
138 }
139
140 if ( lud->lud_attrs != NULL ) {
141 int i;
142
143 for ( i = 0; lud->lud_attrs[i] != NULL; i++ ) {
144 printf( "selector: %s\n", lud->lud_attrs[i] );
145 }
146 }
147
148 if ( lud->lud_scope != LDAP_SCOPE_DEFAULT ) {
149 printf( "scope: %s\n", ldap_pvt_scope2str( lud->lud_scope ) );
150 }
151
152 if ( lud->lud_filter != NULL && lud->lud_filter[0] != '\0' ) {
153 printf( "filter: %s\n", lud->lud_filter );
154 }
155
156 if ( lud->lud_exts != NULL ) {
157 int i;
158
159 for ( i = 0; lud->lud_exts[i] != NULL; i++ ) {
160 printf( "extension: %s\n", lud->lud_exts[i] );
161 }
162 }
163 ldap_free_urldesc( lud );
164
165 return 0;
166 }
167
168 int
main(int argc,char * argv[])169 main( int argc, char *argv[])
170 {
171 LDAPURLDesc lud = { 0 };
172 char *uri = NULL;
173 int gotlud = 0;
174 int nexts = 0;
175
176 lud.lud_port = -1;
177 lud.lud_scope = -1;
178
179 while ( 1 ) {
180 int opt = getopt( argc, argv, "S:h:p:b:a:s:f:E:H:" );
181
182 if ( opt == EOF ) {
183 break;
184 }
185
186 if ( opt == 'H' ) {
187 if ( gotlud ) {
188 fprintf( stderr, "option -H incompatible with previous options\n" );
189 usage();
190 }
191
192 if ( uri != NULL ) {
193 fprintf( stderr, "URI already provided\n" );
194 usage();
195 }
196
197 uri = optarg;
198 continue;
199 }
200
201 switch ( opt ) {
202 case 'S':
203 case 'h':
204 case 'p':
205 case 'b':
206 case 'a':
207 case 's':
208 case 'f':
209 case 'E':
210 if ( uri != NULL ) {
211 fprintf( stderr, "option -%c incompatible with -H\n", opt );
212 usage();
213 }
214 gotlud++;
215 }
216
217 switch ( opt ) {
218 case 'S':
219 if ( lud.lud_scheme != NULL ) {
220 fprintf( stderr, "scheme already provided\n" );
221 usage();
222 }
223 lud.lud_scheme = optarg;
224 break;
225
226 case 'h':
227 if ( lud.lud_host != NULL ) {
228 fprintf( stderr, "host already provided\n" );
229 usage();
230 }
231 lud.lud_host = optarg;
232 break;
233
234 case 'p':
235 if ( lud.lud_port != -1 ) {
236 fprintf( stderr, "port already provided\n" );
237 usage();
238 }
239
240 if ( lutil_atoi( &lud.lud_port, optarg ) ) {
241 fprintf( stderr, "unable to parse port \"%s\"\n", optarg );
242 usage();
243 }
244 break;
245
246 case 'b':
247 if ( lud.lud_dn != NULL ) {
248 fprintf( stderr, "base already provided\n" );
249 usage();
250 }
251 lud.lud_dn = optarg;
252 break;
253
254 case 'a':
255 if ( lud.lud_attrs != NULL ) {
256 fprintf( stderr, "attrs already provided\n" );
257 usage();
258 }
259 lud.lud_attrs = ldap_str2charray( optarg, "," );
260 if ( lud.lud_attrs == NULL ) {
261 fprintf( stderr, "unable to parse attrs list \"%s\"\n", optarg );
262 usage();
263 }
264 break;
265
266 case 's':
267 if ( lud.lud_scope != -1 ) {
268 fprintf( stderr, "scope already provided\n" );
269 usage();
270 }
271
272 lud.lud_scope = ldap_pvt_str2scope( optarg );
273 if ( lud.lud_scope == -1 ) {
274 fprintf( stderr, "unable to parse scope \"%s\"\n", optarg );
275 usage();
276 }
277 break;
278
279 case 'f':
280 if ( lud.lud_filter != NULL ) {
281 fprintf( stderr, "filter already provided\n" );
282 usage();
283 }
284 lud.lud_filter = optarg;
285 break;
286
287 case 'E':
288 lud.lud_exts = (char **)realloc( lud.lud_exts,
289 sizeof( char * ) * ( nexts + 2 ) );
290 lud.lud_exts[ nexts++ ] = optarg;
291 lud.lud_exts[ nexts ] = NULL;
292 break;
293
294 default:
295 assert( opt != 'H' );
296 usage();
297 }
298 }
299
300 if ( uri != NULL ) {
301 return do_uri_explode( uri );
302
303 }
304
305 return do_uri_create( &lud );
306 }
307