]> git.sur5r.net Git - openldap/commitdiff
add slapschema tool (ITS#6150)
authorPierangelo Masarati <ando@openldap.org>
Thu, 28 May 2009 13:40:57 +0000 (13:40 +0000)
committerPierangelo Masarati <ando@openldap.org>
Thu, 28 May 2009 13:40:57 +0000 (13:40 +0000)
servers/slapd/Makefile.in
servers/slapd/main.c
servers/slapd/slapcommon.c
servers/slapd/slapcommon.h
servers/slapd/slapschema.c [new file with mode: 0644]

index e310dfcf0176cbf106c5d273f51a49147aff2fb7..ee784e4282eab6024f13f3c3567ee8243849c94e 100644 (file)
@@ -13,7 +13,7 @@
 ## top-level directory of the distribution or, alternatively, at
 ## <http://www.OpenLDAP.org/license.html>.
 
-SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth slapacl
+SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth slapacl slapschema
 PROGRAMS=slapd $(SLAPTOOLS)
 XPROGRAMS=sslapd libbackends.a .backend liboverlays.a
 XSRCS=version.c
@@ -38,7 +38,7 @@ SRCS  = main.c globals.c bconfig.c config.c daemon.c \
                backglue.c backover.c ctxcsn.c ldapsync.c frontend.c \
                slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
                slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
-               aci.c alock.c txn.c \
+               aci.c alock.c txn.c slapschema.c \
                $(@PLAT@_SRCS)
 
 OBJS   = main.o globals.o bconfig.o config.o daemon.o \
@@ -56,7 +56,7 @@ OBJS  = main.o globals.o bconfig.o config.o daemon.o \
                backglue.o backover.o ctxcsn.o ldapsync.o frontend.o \
                slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
                slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
-               aci.o alock.o txn.o \
+               aci.o alock.o txn.o slapschema.o \
                $(@PLAT@_OBJS)
 
 LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I.
index 64d1876dc747acac227ebdfe235662b0c51ab2d5..14fadd6b1acd4741a254d5baebe4ac91c57e23b3 100644 (file)
@@ -65,7 +65,7 @@ static struct sockaddr_in     bind_addr;
 
 typedef int (MainFunc) LDAP_P(( int argc, char *argv[] ));
 extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd,
-       slaptest, slapauth, slapacl;
+       slaptest, slapauth, slapacl, slapschema;
 
 static struct {
        char *name;
@@ -76,6 +76,7 @@ static struct {
        {"slapdn", slapdn},
        {"slapindex", slapindex},
        {"slappasswd", slappasswd},
+       {"slapschema", slapschema},
        {"slaptest", slaptest},
        {"slapauth", slapauth},
        {"slapacl", slapacl},
index 8d4527c9fc2a6bce2dba95f7571042ddf6cef363..74b9e1b332b468b2bb695fd5047253fee20013f2 100644 (file)
@@ -94,6 +94,11 @@ usage( int tool, const char *progname )
        case SLAPTEST:
                options = " [-u]\n";
                break;
+
+       case SLAPSCHEMA:
+               options = " [-c]\n\t[-g] [-n databasenumber | -b suffix]"
+                       " [-l errorfile] [-a filter] [-s subtree]\n";
+               break;
        }
 
        if ( options != NULL ) {
@@ -222,6 +227,7 @@ slap_tool_init(
        int mode = SLAP_TOOL_MODE;
        int truncatemode = 0;
        int use_glue = 1;
+       int writer;
 
 #ifdef LDAP_DEBUG
        /* tools default to "none", so that at least LDAP_DEBUG_ANY 
@@ -255,6 +261,11 @@ slap_tool_init(
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
                break;
 
+       case SLAPSCHEMA:
+               options = "a:b:cd:f:F:gl:n:o:s:v";
+               mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
+               break;
+
        case SLAPTEST:
                options = "d:f:F:o:Quv";
                mode |= SLAP_TOOL_READMAIN | SLAP_TOOL_READONLY;
@@ -396,7 +407,7 @@ slap_tool_init(
                case 's':       /* dump subtree */
                        if ( tool == SLAPADD )
                                mode |= SLAP_TOOL_NO_SCHEMA_CHECK;
-                       else if ( tool == SLAPCAT )
+                       else if ( tool == SLAPCAT || tool == SLAPSCHEMA )
                                subtree = ch_strdup( optarg );
                        break;
 
@@ -453,9 +464,21 @@ slap_tool_init(
        }
 #endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
+       switch ( tool ) {
+       case SLAPCAT:
+       case SLAPSCHEMA:
+               writer = 1;
+               break;
+
+       default:
+               writer = 0;
+               break;
+       }
+
        switch ( tool ) {
        case SLAPADD:
        case SLAPCAT:
+       case SLAPSCHEMA:
                if ( ( argc != optind ) || (dbnum >= 0 && base.bv_val != NULL ) ) {
                        usage( tool, progname );
                }
@@ -502,10 +525,10 @@ slap_tool_init(
        }
 
        if ( ldiffile == NULL ) {
-               dummy.fp = tool == SLAPCAT ? stdout : stdin;
+               dummy.fp = writer ? stdout : stdin;
                ldiffp = &dummy;
 
-       } else if ((ldiffp = ldif_open( ldiffile, tool == SLAPCAT ? "w" : "r" ))
+       } else if ((ldiffp = ldif_open( ldiffile, writer ? "w" : "r" ))
                == NULL )
        {
                perror( ldiffile );
@@ -554,6 +577,7 @@ slap_tool_init(
        case SLAPADD:
        case SLAPCAT:
        case SLAPINDEX:
+       case SLAPSCHEMA:
                if ( !nbackends ) {
                        fprintf( stderr, "No databases found "
                                        "in config file\n" );
index b030da2874768225bc1082b066be7abcac6ec4f3..56b21cd6481030b839d7891958d990ddf1e3a84f 100644 (file)
@@ -26,6 +26,7 @@ enum slaptool {
        SLAPDN,         /* DN check w/ syntax tool */
        SLAPINDEX,      /* database index tool */
        SLAPPASSWD,     /* password generation tool */
+       SLAPSCHEMA,     /* schema checking tool */
        SLAPTEST,       /* slapd.conf test tool */
        SLAPAUTH,       /* test authz-regexp and authc/authz stuff */
        SLAPACL,        /* test acl */
diff --git a/servers/slapd/slapschema.c b/servers/slapd/slapschema.c
new file mode 100644 (file)
index 0000000..6a00be8
--- /dev/null
@@ -0,0 +1,142 @@
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2009 The OpenLDAP Foundation.
+ * Portions Copyright 1998-2003 Kurt D. Zeilenga.
+ * Portions Copyright 2003 IBM Corporation.
+ * 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 file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software.  Code portions borrowed from slapcat.c;
+ * contributors are Kurt Zeilenga and Jong Hyuk Choi
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include "ac/stdlib.h"
+#include "ac/ctype.h"
+#include "ac/socket.h"
+#include "ac/string.h"
+
+#include "slapcommon.h"
+#include "ldif.h"
+
+static volatile sig_atomic_t gotsig;
+
+static RETSIGTYPE
+slapcat_sig( int sig )
+{
+       gotsig=1;
+}
+
+int
+slapschema( int argc, char **argv )
+{
+       ID id;
+       int rc = EXIT_SUCCESS;
+       const char *progname = "slapschema";
+       Connection conn = { 0 };
+       OperationBuffer opbuf;
+       Operation *op = NULL;
+
+       slap_tool_init( progname, SLAPCAT, argc, argv );
+
+#ifdef SIGPIPE
+       (void) SIGNAL( SIGPIPE, slapcat_sig );
+#endif
+#ifdef SIGHUP
+       (void) SIGNAL( SIGHUP, slapcat_sig );
+#endif
+       (void) SIGNAL( SIGINT, slapcat_sig );
+       (void) SIGNAL( SIGTERM, slapcat_sig );
+
+       if( !be->be_entry_open ||
+               !be->be_entry_close ||
+               !be->be_entry_first ||
+               !be->be_entry_next ||
+               !be->be_entry_get )
+       {
+               fprintf( stderr, "%s: database doesn't support necessary operations.\n",
+                       progname );
+               exit( EXIT_FAILURE );
+       }
+
+       if( be->be_entry_open( be, 0 ) != 0 ) {
+               fprintf( stderr, "%s: could not open database.\n",
+                       progname );
+               exit( EXIT_FAILURE );
+       }
+
+       connection_fake_init( &conn, &opbuf, &conn );
+       op = &opbuf.ob_op;
+       op->o_tmpmemctx = NULL;
+       op->o_bd = be;
+
+       for ( id = be->be_entry_first( be );
+               id != NOID;
+               id = be->be_entry_next( be ) )
+       {
+               Entry* e;
+               char textbuf[SLAP_TEXT_BUFLEN];
+               size_t textlen = sizeof(textbuf);
+               const char *text = NULL;
+
+               if ( gotsig )
+                       break;
+
+               e = be->be_entry_get( be, id );
+               if ( e == NULL ) {
+                       printf("# no data for entry id=%08lx\n\n", (long) id );
+                       rc = EXIT_FAILURE;
+                       if( continuemode ) continue;
+                       break;
+               }
+
+               if( sub_ndn.bv_len && !dnIsSuffix( &e->e_nname, &sub_ndn ) ) {
+                       be_entry_release_r( op, e );
+                       continue;
+               }
+
+               if( filter != NULL ) {
+                       int rc = test_filter( NULL, e, filter );
+                       if( rc != LDAP_COMPARE_TRUE ) {
+                               be_entry_release_r( op, e );
+                               continue;
+                       }
+               }
+
+               if( verbose ) {
+                       printf( "# id=%08lx\n", (long) id );
+               }
+
+               rc = entry_schema_check( op, e, NULL, 0, 0, NULL,
+                       &text, textbuf, textlen );
+               if ( rc != LDAP_SUCCESS ) {
+                       fprintf( ldiffp->fp, "# (%d) %s%s%s\n",
+                               rc, ldap_err2string( rc ),
+                               text ? ": " : "",
+                               text ? text : "" );
+                       fprintf( ldiffp->fp, "dn: %s\n\n", e->e_name.bv_val );
+               }
+
+               be_entry_release_r( op, e );
+       }
+
+       be->be_entry_close( be );
+
+       if ( slap_tool_destroy() )
+               rc = EXIT_FAILURE;
+
+       return rc;
+}