]> git.sur5r.net Git - openldap/commitdiff
add ldapurl command
authorPierangelo Masarati <ando@openldap.org>
Sun, 19 Oct 2008 20:35:18 +0000 (20:35 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 19 Oct 2008 20:35:18 +0000 (20:35 +0000)
clients/tools/Makefile.in
clients/tools/ldapurl.c [new file with mode: 0644]
doc/devel/args
doc/man/man1/ldapurl.1 [new file with mode: 0644]

index 6fd0578faeaafa90c055415f3f2f480a01407fba..e8b70556cb8a9621ef64f49968529696f3721576 100644 (file)
 
 SRCS   = ldapsearch.c ldapmodify.c ldapdelete.c ldapmodrdn.c \
                ldappasswd.c ldapwhoami.c ldapcompare.c \
-               ldapexop.c common.c
+               ldapexop.c ldapurl.c common.c
 OBJS   = ldapsearch.o ldapmodify.o ldapdelete.o ldapmodrdn.o \
                ldappasswd.o ldapwhoami.o ldapcompare.o \
-               ldapexop.o common.o
+               ldapexop.o ldapurl.o common.o
 
 LDAP_INCDIR= ../../include       
 LDAP_LIBDIR= ../../libraries
@@ -29,10 +29,10 @@ XLIBS =  $(LDAP_L)
 XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS)
 
 XSRCS  = ldsversion.c ldmversion.c lddversion.c ldrversion.c \
-       ldpversion.c ldwversion.c ldcversion.c ldeversion.c
+       ldpversion.c ldwversion.c ldcversion.c ldeversion.c lduversion.c
 
 PROGRAMS = ldapsearch ldapmodify ldapdelete ldapmodrdn \
-       ldappasswd ldapwhoami ldapcompare ldapexop
+       ldappasswd ldapwhoami ldapcompare ldapexop ldapurl
 
 
 ldapsearch:    ldsversion.o
@@ -59,6 +59,9 @@ ldapcompare: ldcversion.o
 ldapexop: ldeversion.o
        $(LTLINK) -o $@ ldapexop.o common.o ldeversion.o $(LIBS)
 
+ldapurl: lduversion.o
+       $(LTLINK) -o $@ ldapurl.o lduversion.o $(LIBS)
+
 ldsversion.c: Makefile
        @-$(RM) $@
        $(MKVERSION) $(MKVOPTS) ldapsearch > $@
@@ -107,6 +110,12 @@ ldeversion.c: Makefile
 
 ldeversion.o: ldapexop.o common.o $(XLIBS)
 
+lduversion.c: Makefile
+       @-$(RM) $@
+       $(MKVERSION) $(MKVOPTS) ldapurl > $@
+
+lduversion.o: ldapurl.o $(XLIBS)
+
 install-local: FORCE
        -$(MKDIR) $(DESTDIR)$(bindir)
        @(                                                              \
diff --git a/clients/tools/ldapurl.c b/clients/tools/ldapurl.c
new file mode 100644 (file)
index 0000000..eb7f964
--- /dev/null
@@ -0,0 +1,304 @@
+/* ldapurl -- a tool for generating LDAP URLs */
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2008 The OpenLDAP Foundation.
+ * Portions Copyright 2008 Pierangelo Masarati, SysNet
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.  This
+ * software is provided ``as is'' without express or implied warranty.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was originally developed by Pierangelo Masarati
+ * for inclusion in OpenLDAP software.
+ */
+
+#include "portable.h"
+
+#include <ac/stdlib.h>
+#include <stdio.h>
+#include <ac/unistd.h>
+
+#include "ldap.h"
+#include "ldap_pvt.h"
+#include "lutil.h"
+
+static int
+usage(void)
+{
+       fprintf( stderr, _("usage: %s [options]\n\n"), "ldapurl" );
+       fprintf( stderr, _("generates RFC 4516 LDAP URL with extensions\n\n" ) );
+       fprintf( stderr, _("URL options:\n"));
+       fprintf( stderr, _("  -a attrs   comma separated list of attributes\n" ) );
+       fprintf( stderr, _("  -b base    (RFC 4514 LDAP DN)\n" ) );
+       fprintf( stderr, _("  -E ext     (format: \"ext=value\"; multiple occurrences allowed)\n" ) );
+       fprintf( stderr, _("  -f filter  (RFC 4515 LDAP filter)\n" ) );
+       fprintf( stderr, _("  -h host    \n" ) );
+       fprintf( stderr, _("  -p port    (default: 389 for ldap, 636 for ldaps)\n" ) );
+       fprintf( stderr, _("  -s scope   (RFC 4511 searchScope and extensions)\n" ) );
+       fprintf( stderr, _("  -S scheme  (RFC 4516 LDAP URL scheme and extensions)\n" ) );
+       exit( EXIT_FAILURE );
+}
+
+static int
+do_uri_create( LDAPURLDesc *lud )
+{
+       char    *uri;
+
+       if ( lud->lud_scheme == NULL ) {
+               lud->lud_scheme = "ldap";
+       }
+
+       if ( lud->lud_port == -1 ) {
+               if ( strcasecmp( lud->lud_scheme, "ldap" ) == 0 ) {
+                       lud->lud_port = LDAP_PORT;
+
+               } else if ( strcasecmp( lud->lud_scheme, "ldaps" ) == 0 ) {
+                       lud->lud_port = LDAPS_PORT;
+
+               } else if ( strcasecmp( lud->lud_scheme, "ldapi" ) == 0 ) {
+                       lud->lud_port = 0;
+
+               } else {
+                       /* forgiving... */
+                       lud->lud_port = 0;
+               }
+       }
+
+       if ( lud->lud_scope == -1 ) {
+               lud->lud_scope = LDAP_SCOPE_DEFAULT;
+       }
+
+       uri = ldap_url_desc2str( lud );
+
+       if ( lud->lud_attrs != NULL ) {
+               ldap_charray_free( lud->lud_attrs );
+               lud->lud_attrs = NULL;
+       }
+
+       if ( lud->lud_exts != NULL ) {
+               free( lud->lud_exts );
+               lud->lud_exts = NULL;
+       }
+
+       if ( uri == NULL ) {
+               fprintf( stderr, "unable to generate URI\n" );
+               exit( EXIT_FAILURE );
+       }
+
+       printf( "%s\n", uri );
+       free( uri );
+
+       return 0;
+}
+
+static int
+do_uri_explode( const char *uri )
+{
+       LDAPURLDesc     *lud;
+       int             rc;
+
+       rc = ldap_url_parse( uri, &lud );
+       if ( rc != LDAP_URL_SUCCESS ) {
+               fprintf( stderr, "unable to parse URI \"%s\"\n", uri );
+               return 1;
+       }
+
+       if ( lud->lud_scheme != NULL && lud->lud_scheme[0] != '\0' ) {
+               printf( "scheme: %s\n", lud->lud_scheme );
+       }
+
+       if ( lud->lud_host != NULL && lud->lud_host[0] != '\0' ) {
+               printf( "host: %s\n", lud->lud_host );
+       }
+
+       if ( lud->lud_port != 0 ) {
+               printf( "port: %d\n", lud->lud_port );
+       }
+
+       if ( lud->lud_dn != NULL && lud->lud_dn[0] != '\0' ) {
+               printf( "dn: %s\n", lud->lud_dn );
+       }
+
+       if ( lud->lud_attrs != NULL ) {
+               int     i;
+
+               for ( i = 0; lud->lud_attrs[i] != NULL; i++ ) {
+                       printf( "selector: %s\n", lud->lud_attrs[i] );
+               }
+       }
+
+       if ( lud->lud_scope != LDAP_SCOPE_DEFAULT ) {
+               printf( "scope: %s\n", ldap_pvt_scope2str( lud->lud_scope ) );
+       }
+
+       if ( lud->lud_filter != NULL && lud->lud_filter[0] != '\0' ) {
+               printf( "filter: %s\n", lud->lud_filter );
+       }
+
+       if ( lud->lud_exts != NULL ) {
+               int     i;
+
+               for ( i = 0; lud->lud_exts[i] != NULL; i++ ) {
+                       printf( "extension: %s\n", lud->lud_exts[i] );
+               }
+       }
+
+       return 0;
+}
+
+int
+main( int argc, char *argv[])
+{
+       LDAPURLDesc     lud = { 0 };
+       char            *uri = NULL;
+       int             gotlud = 0;
+       int             nexts = 0;
+
+       lud.lud_port = -1;
+       lud.lud_scope = -1;
+
+       while ( 1 ) {
+               int opt = getopt( argc, argv, "S:h:p:b:a:s:f:E:H:" );
+
+               if ( opt == EOF ) {
+                       break;
+               }
+
+               if ( opt == 'H' ) {
+                       if ( gotlud ) {
+                               fprintf( stderr, "option -H incompatible with previous options\n" );
+                               usage();
+                       }
+
+                       if ( uri != NULL ) {
+                               fprintf( stderr, "URI already provided\n" );
+                               usage();
+                       }
+
+                       uri = optarg;
+                       continue;
+               }
+
+               switch ( opt ) {
+               case 'S':
+               case 'h':
+               case 'p':
+               case 'b':
+               case 'a':
+               case 's':
+               case 'f':
+               case 'E':
+                       if ( uri != NULL ) {
+                               fprintf( stderr, "option -%c incompatible with -H\n", opt );
+                               usage();
+                       }
+                       gotlud++;
+               }
+
+               switch ( opt ) {
+               case 'S':
+                       if ( lud.lud_scheme != NULL ) {
+                               fprintf( stderr, "scheme already provided\n" );
+                               usage();
+                       }
+                       lud.lud_scheme = optarg;
+                       break;
+
+               case 'h':
+                       if ( lud.lud_host != NULL ) {
+                               fprintf( stderr, "host already provided\n" );
+                               usage();
+                       }
+                       lud.lud_host = optarg;
+                       break;
+
+               case 'p':
+                       if ( lud.lud_port != -1 ) {
+                               fprintf( stderr, "port already provided\n" );
+                               usage();
+                       }
+
+                       if ( lutil_atoi( &lud.lud_port, optarg ) ) {
+                               fprintf( stderr, "unable to parse port \"%s\"\n", optarg );
+                               usage();
+                       }
+                       break;
+
+               case 'b':
+                       if ( lud.lud_dn != NULL ) {
+                               fprintf( stderr, "base already provided\n" );
+                               usage();
+                       }
+                       lud.lud_dn = optarg;
+                       break;
+
+               case 'a':
+                       if ( lud.lud_attrs != NULL ) {
+                               fprintf( stderr, "attrs already provided\n" );
+                               usage();
+                       }
+                       lud.lud_attrs = ldap_str2charray( optarg, "," );
+                       if ( lud.lud_attrs == NULL ) {
+                               fprintf( stderr, "unable to parse attrs list \"%s\"\n", optarg );
+                               usage();
+                       }
+                       break;
+
+               case 's':
+                       if ( lud.lud_scope != -1 ) {
+                               fprintf( stderr, "scope already provided\n" );
+                               usage();
+                       }
+
+                       lud.lud_scope = ldap_pvt_str2scope( optarg );
+                       if ( lud.lud_scope == -1 ) {
+                               fprintf( stderr, "unable to parse scope \"%s\"\n", optarg );
+                               usage();
+                       }
+                       break;
+
+               case 'f':
+                       if ( lud.lud_filter != NULL ) {
+                               fprintf( stderr, "filter already provided\n" );
+                               usage();
+                       }
+                       lud.lud_filter = optarg;
+                       break;
+
+               case 'E':
+                       lud.lud_exts = (char **)realloc( lud.lud_exts,
+                               sizeof( char * ) * ( nexts + 2 ) );
+                       lud.lud_exts[ nexts++ ] = optarg;
+                       lud.lud_exts[ nexts ] = NULL;
+                       break;
+
+               default:
+                       assert( opt != 'H' );
+                       usage();
+               }
+       }
+
+       if ( uri != NULL ) {
+               return do_uri_explode( uri );
+
+       }
+
+       return do_uri_create( &lud );
+}
index 69316da0f5adacff83fb26e66b15033791120568..60de07df78163d6a2da0b093220dc3ad64d4bb9e 100644 (file)
@@ -5,6 +5,7 @@ ldapmodify       *CDE**HI*K M*OPQRS UVWXYZabcde *h**k *nop*r t vwxy
 ldapmodrdn       *CDE**HI*K M*OPQR  UVWXYZ  cdef*h**k *nop*rs  vwxy
 ldappasswd      A*CDE**HI*   *O QRS UVWXYZa  def*h**  * o * s  vwxy  
 ldapsearch      A*CDE**HI*KLM*OPQRSTUVWXYZab def*h**kl*nop* stuvwxyz
+ldapurl          *  E**H *   *    S       ab   f*h**  *  p* s
 ldapwhoami       * DE**HI*   *O QR  UVWXYZ   def*h**  *nop*    vwxy 
 
 
diff --git a/doc/man/man1/ldapurl.1 b/doc/man/man1/ldapurl.1
new file mode 100644 (file)
index 0000000..3806133
--- /dev/null
@@ -0,0 +1,141 @@
+.TH LDAPURL 1 "RELEASEDATE" "OpenLDAP LDVERSION"
+.\" $OpenLDAP$
+.\" Copyright 2008 The OpenLDAP Foundation All Rights Reserved.
+.\" Copying restrictions apply.  See COPYRIGHT/LICENSE.
+.SH NAME
+ldapurl \- LDAP URL formatting tool
+.SH SYNOPSIS
+.B ldapurl
+[\c
+.BR \-a \ attrs\fR]
+[\c
+.BI \-b \ searchbase\fR]
+[\c
+.BR \-E \ [!]ext[=extparam]]
+[\c
+.BI \-f \ filter\fR]
+[\c
+.BI \-H \ ldapuri\fR]
+[\c
+.BI \-h \ ldaphost\fR]
+[\c
+.BI \-p \ ldapport\fR]
+[\c
+.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren\fR]
+[\c
+.BI \-S \ scheme\fR]
+.SH DESCRIPTION
+.I ldapurl
+is a command that allows to either compose or decompose LDAP URIs.
+.LP
+When invoked with the \fI-H\fP option,
+.B ldapurl
+extracts the components of the \fIldapuri\fP option argument,
+unescaping hex-escaped chars as required.
+It basically acts as a frontend to the
+.BR ldap_url_parse (3)
+call.
+Otherwise, it builds an LDAP URI based on the components
+passed with the appropriate options, performing the inverse operation.
+Option \fI-H\fP is incompatible with options
+.IR \-a ,
+.IR \-b ,
+.IR \-E ,
+.IR \-f ,
+.IR \-H ,
+.IR \-h ,
+.IR \-p ,
+.IR \-S ,
+and
+.IR \-s .
+.SH OPTIONS
+.TP
+.TP
+.BI \-a \ attrs
+Set a comma-separated list of attribute selectors.
+.TP
+.BI \-b \ searchbase
+Set the \fIsearchbase\fP.
+.TP
+.B \-E \fI[!]ext[=extparam]\fP
+Set URL extensions; \'!\' indicates criticality.
+.TP
+.BI \-f \ filter
+Set the URL filter.  No particular check on conformity with RFC 4515
+LDAP filters is performed, but the value is hex-escaped as required.
+.TP
+.BI \-H \ ldapuri
+Specify URI to be exploded.
+.TP
+.BI \-h \ ldaphost
+Set the host.
+.TP
+.BI \-p \ ldapport
+Set the TCP port.
+.TP
+.BI \-S \ scheme
+Set the URL scheme.  Defaults for other fields, like \fIldapport\fP,
+may depend on the value of \fIscheme\fP.
+.TP
+.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren
+Specify the scope of the search to be one of
+.IR base ,
+.IR one ,
+.IR sub ,
+or
+.I children
+to specify a base object, one-level, subtree, or children search.
+The default is
+.IR sub .
+Note:
+.I children
+scope requires LDAPv3 subordinate feature extension.
+
+.SH OUTPUT FORMAT
+If the \fI-H\fP option is used, the \fIldapuri\fP supplied
+is exploded in its components, which are printed to standard output
+in an LDIF-like form.
+.LP
+Otherwise, the URI built using the values passed with the other options
+is printed to standard output.
+.SH EXAMPLE
+The following command:
+.LP
+.nf
+    ldapuri -h ldap.example.com -b dc=example,dc=com -s sub -f (cn=Some One)
+.fi
+.LP
+returns
+.LP
+.nf
+    ldap://ldap.example.com:389/dc=example,dc=com??sub?(cn=Some%20One)
+.fi
+.LP
+The command:
+.LP
+.nf
+    ldapuri -H ldap://ldap.example.com:389/dc=example,dc=com??sub?(cn=Some%20One)
+.fi
+.LP
+returns
+.LP
+.nf
+    scheme: ldap
+    host: ldap.example.com
+    port: 389
+    dn: dc=example,dc=com
+    scope: sub
+    filter: (cn=Some One)
+.fi
+.LP
+.SH DIAGNOSTICS
+Exit status is zero if no errors occur.
+Errors result in a non-zero exit status and
+a diagnostic message being written to standard error.
+.SH "SEE ALSO"
+.BR ldap (3),
+.BR ldap_url_parse (3),
+.SH AUTHOR
+The OpenLDAP Project <http://www.openldap.org/>
+.SH ACKNOWLEDGEMENTS
+.so ../Project