From 57e68fa5b3bd7d10f6e56eda8f0320e5b82f6117 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Thu, 28 May 2009 13:40:57 +0000 Subject: [PATCH] add slapschema tool (ITS#6150) --- servers/slapd/Makefile.in | 6 +- servers/slapd/main.c | 3 +- servers/slapd/slapcommon.c | 30 +++++++- servers/slapd/slapcommon.h | 1 + servers/slapd/slapschema.c | 142 +++++++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 7 deletions(-) create mode 100644 servers/slapd/slapschema.c diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index e310dfcf01..ee784e4282 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -13,7 +13,7 @@ ## top-level directory of the distribution or, alternatively, at ## . -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. diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 64d1876dc7..14fadd6b1a 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -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}, diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 8d4527c9fc..74b9e1b332 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -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" ); diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index b030da2874..56b21cd648 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -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 index 0000000000..6a00be85c7 --- /dev/null +++ b/servers/slapd/slapschema.c @@ -0,0 +1,142 @@ +/* $OpenLDAP$ */ +/* This work is part of OpenLDAP Software . + * + * 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 + * . + */ +/* 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 + +#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; +} -- 2.39.5