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