From 52ad705e58c8ebec923c26a18e2ff95a7e7b8be4 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Mon, 3 Jan 2011 20:07:19 +0000
Subject: [PATCH] ITS#6592

---
 CHANGES                    |  1 +
 doc/man/man8/slapadd.8     |  8 +++++++-
 servers/slapd/slap.h       |  1 +
 servers/slapd/slapadd.c    | 36 ++++++++++++++++++++++++++++++++++++
 servers/slapd/slapcommon.c | 36 ++++++++++++++++++++++++++++++++++++
 5 files changed, 81 insertions(+), 1 deletion(-)

diff --git a/CHANGES b/CHANGES
index 681b71e649..2b867bb816 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,7 @@
 OpenLDAP 2.4 Change Log
 
 OpenLDAP 2.4.24 Engineering
+	Addes slapadd attribute value checking (ITS#6592)
 	Added slapd-null back-config support (ITS#6624)
 	Added slapd-sql autocommit support (ITS#6612)
 	Addes slapd-sql support for long long keys (ITS#6617)
diff --git a/doc/man/man8/slapadd.8 b/doc/man/man8/slapadd.8
index a56aedeaed..ed3648b70b 100644
--- a/doc/man/man8/slapadd.8
+++ b/doc/man/man8/slapadd.8
@@ -147,7 +147,13 @@ Possible generic options/values are:
               syslog\-level=<level> (see `\-S' in slapd(8))
               syslog\-user=<user>   (see `\-l' in slapd(8))
 
-.fi
+              schema-check={yes|no}
+              value-check={yes|no}
+
+.in
+The \fIschema\-check\fR option toggles schema checking (default on);
+the \fIvalue\-check\fR option toggles value checking (default off).
+The latter is incompatible with \fB-q\fR.
 .TP
 .B \-q
 enable quick (fewer integrity checks) mode.  Does fewer consistency checks
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index e082c321a7..a85a939c9b 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1588,6 +1588,7 @@ LDAP_SLAPD_V (int) slapMode;
 #define	SLAP_TOOL_READONLY	0x0400
 #define	SLAP_TOOL_QUICK		0x0800
 #define SLAP_TOOL_NO_SCHEMA_CHECK	0x1000
+#define SLAP_TOOL_VALUE_CHECK	0x2000
 
 #define SB_TLS_DEFAULT		(-1)
 #define SB_TLS_OFF		0
diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c
index fe205eafb5..d88e121971 100644
--- a/servers/slapd/slapadd.c
+++ b/servers/slapd/slapadd.c
@@ -103,6 +103,14 @@ slapadd( int argc, char **argv )
 
 	checkvals = (slapMode & SLAP_TOOL_QUICK) ? 0 : 1;
 
+	/* do not check values in quick mode */
+	if ( slapMode & SLAP_TOOL_QUICK ) {
+		if ( slapMode & SLAP_TOOL_VALUE_CHECK ) {
+			fprintf( stderr, "%s: value-check incompatible with quick mode; disabled.\n", progname );
+			slapMode &= ~SLAP_TOOL_VALUE_CHECK;
+		}
+	}
+
 	lmax = 0;
 	nextline = 0;
 
@@ -267,6 +275,34 @@ slapadd( int argc, char **argv )
 				}
 				textbuf[ 0 ] = '\0';
 			}
+
+			if ( (slapMode & SLAP_TOOL_VALUE_CHECK) != 0) {
+				Modifications *ml = NULL;
+
+				if ( slap_entry2mods( e, &ml, &text, textbuf, textlen )
+					!= LDAP_SUCCESS )
+				{
+					fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
+						progname, e->e_dn, lineno, rc, text );
+					rc = EXIT_FAILURE;
+					entry_free( e );
+					if( continuemode ) continue;
+					break;
+				}
+				textbuf[ 0 ] = '\0';
+
+				rc = slap_mods_check( op, ml, &text, textbuf, textlen, NULL );
+				slap_mods_free( ml, 1 );
+				if ( rc != LDAP_SUCCESS ) {
+					fprintf( stderr, "%s: dn=\"%s\" (line=%d): (%d) %s\n",
+						progname, e->e_dn, lineno, rc, text );
+					rc = EXIT_FAILURE;
+					entry_free( e );
+					if( continuemode ) continue;
+					break;
+				}
+				textbuf[ 0 ] = '\0';
+			}
 		}
 
 		if ( SLAP_LASTMOD(be) ) {
diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c
index 3a39c7de73..1b5a594cac 100644
--- a/servers/slapd/slapcommon.c
+++ b/servers/slapd/slapcommon.c
@@ -192,6 +192,42 @@ parse_slapopt( int tool, int *mode )
 #endif /* LOG_LOCAL4 */
 #endif /* LDAP_DEBUG && LDAP_SYSLOG */
 
+	} else if ( strncasecmp( optarg, "schema-check", len ) == 0 ) {
+		switch ( tool ) {
+		case SLAPADD:
+			if ( strcasecmp( p, "yes" ) == 0 ) {
+				*mode &= ~SLAP_TOOL_NO_SCHEMA_CHECK;
+			} else if ( strcasecmp( p, "no" ) == 0 ) {
+				*mode |= SLAP_TOOL_NO_SCHEMA_CHECK;
+			} else {
+				Debug( LDAP_DEBUG_ANY, "unable to parse schema-check=\"%s\".\n", p, 0, 0 );
+				return -1;
+			}
+			break;
+
+		default:
+			Debug( LDAP_DEBUG_ANY, "schema-check meaningless for tool.\n", 0, 0, 0 );
+			break;
+		}
+
+	} else if ( strncasecmp( optarg, "value-check", len ) == 0 ) {
+		switch ( tool ) {
+		case SLAPADD:
+			if ( strcasecmp( p, "yes" ) == 0 ) {
+				*mode |= SLAP_TOOL_VALUE_CHECK;
+			} else if ( strcasecmp( p, "no" ) == 0 ) {
+				*mode &= ~SLAP_TOOL_VALUE_CHECK;
+			} else {
+				Debug( LDAP_DEBUG_ANY, "unable to parse value-check=\"%s\".\n", p, 0, 0 );
+				return -1;
+			}
+			break;
+
+		default:
+			Debug( LDAP_DEBUG_ANY, "value-check meaningless for tool.\n", 0, 0, 0 );
+			break;
+		}
+
 	} else {
 		return -1;
 	}
-- 
GitLab