summaryrefslogtreecommitdiff
path: root/source4/dsdb/samdb/ldb_modules/schema_syntax.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/schema_syntax.c')
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_syntax.c373
1 files changed, 373 insertions, 0 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/schema_syntax.c b/source4/dsdb/samdb/ldb_modules/schema_syntax.c
new file mode 100644
index 0000000000..02c42bbf8f
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/schema_syntax.c
@@ -0,0 +1,373 @@
+/*
+ ldb database library
+
+ Copyright (C) Simo Sorce 2004-2006
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+ * Name: ldb
+ *
+ * Component: ldb schema module
+ *
+ * Description: add schema syntax functionality
+ *
+ * Author: Simo Sorce
+ *
+ * License: GNU GPL v2 or Later
+ */
+
+#include "includes.h"
+#include "ldb/include/ldb.h"
+#include "ldb/include/ldb_errors.h"
+#include "schema_syntax.h"
+
+static int schema_validate_boolean(struct ldb_val *val, int min, int max)
+{
+
+ if ((strncmp("TRUE", (const char *)val->data, val->length) != 0) &&
+ (strncmp("FALSE", (const char *)val->data, val->length) != 0)) {
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_integer(struct ldb_val *val, int min, int max)
+{
+ int value;
+ char *endptr;
+
+ errno = 0;
+ value = strtol((const char *)val->data, &endptr, 0);
+ if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if (endptr[0] != '\0') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((min > INT_MIN) && (value < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((max < INT_MAX) && (value > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_binary_blob(struct ldb_val *val, int min, int max)
+{
+ /* is there anythign we should check in a binary blob ? */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_sid(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate binary form of objectSid */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_oid(struct ldb_val *val, int min, int max)
+{
+ if (strspn((const char *)val->data, "0123456789.") != val->length)
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_numeric_string(struct ldb_val *val, int min, int max)
+{
+ if (strspn((const char *)val->data, "0123456789") != val->length)
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_printable_string(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what constitutes the printable character set */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_teletext_string(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what constitutes the teletext character set */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_ia5_string(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what constitutes the IA5 character set */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_utc_time(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate syntax of UTC Time string */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_generalized_time(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate syntax of Generalized Time string */
+ return LDB_SUCCESS;
+}
+
+/* NOTE: not a single attribute has this syntax in the basic w2k3 schema */
+static int schema_validate_sensitive_string(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what constitutes a "case sensitive string" */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_unicode_string(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate utf8 string */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_large_integer(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate large integer/interval */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_object_sd(struct ldb_val *val, int min, int max)
+{
+ /* TODO: validate object Security Descriptor */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_dn(struct ldb_val *val, int min, int max)
+{
+ TALLOC_CTX *memctx;
+ struct ldb_dn *dn;
+ int ret = LDB_SUCCESS;
+
+ memctx = talloc_new(NULL);
+ if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
+
+ dn = ldb_dn_explode(memctx, (const char *)val->data);
+ if (!dn) {
+ ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
+
+ talloc_free(memctx);
+ return ret;
+}
+
+static int schema_validate_binary_plus_dn(struct ldb_val *val, int min, int max)
+{
+ int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ TALLOC_CTX *memctx;
+ struct ldb_dn *dn;
+ char *str, *p;
+ char *endptr;
+ int num;
+
+ memctx = talloc_new(NULL);
+ if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
+
+ str = talloc_strdup(memctx, (const char *)val->data);
+ if (!str) {
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto done;
+ }
+ if (strncasecmp(str, "B:", 2) != 0) {
+ goto done;
+ }
+
+ /* point at the number of chars in the string */
+ str = strchr(&str[2], ':');
+ if (!str) {
+ goto done;
+ }
+ str++;
+
+ errno = 0;
+ num = strtol(str, &endptr, 0);
+ if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+
+ /* point at the string */
+ str = strchr(str, ':');
+ if (!str) {
+ goto done;
+ }
+ str++;
+
+ /* terminate the string */
+ p = strchr(str, ':');
+ if (!p) {
+ goto done;
+ }
+ *p = '\0';
+
+ if (strlen(str) != 2*num) {
+ goto done;
+ }
+
+ str = p + 1;
+
+ dn = ldb_dn_explode(memctx, str);
+ if (dn) {
+ ret = LDB_SUCCESS;
+ }
+
+done:
+ talloc_free(memctx);
+ return ret;
+}
+
+static int schema_validate_x400_or_name(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what is the syntax of an X400 OR NAME */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_presentation_address(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what is the syntax of a presentation address */
+ return LDB_SUCCESS;
+}
+
+static int schema_validate_x400_access_point(struct ldb_val *val, int min, int max)
+{
+ /* TODO: find out what is the syntax of an X400 Access Point */
+ return LDB_SUCCESS;
+}
+
+/* NOTE: seem there isn't a single attribute defined like this in the base w2k3 schema */
+static int schema_validate_string_plus_dn(struct ldb_val *val, int min, int max)
+{
+ int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ TALLOC_CTX *memctx;
+ struct ldb_dn *dn;
+ char *str, *p;
+ char *endptr;
+ int num;
+
+ memctx = talloc_new(NULL);
+ if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
+
+ str = talloc_strdup(memctx, (const char *)val->data);
+ if (!str) {
+ ret = LDB_ERR_OPERATIONS_ERROR;
+ goto done;
+ }
+ if (strncasecmp(str, "S:", 2) != 0) {
+ goto done;
+ }
+
+ /* point at the number of chars in the string */
+ str = strchr(&str[2], ':');
+ if (!str) {
+ goto done;
+ }
+ str++;
+
+ errno = 0;
+ num = strtol(str, &endptr, 0);
+ if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+
+ /* point at the string */
+ str = strchr(str, ':');
+ if (!str) {
+ goto done;
+ }
+ str++;
+
+ /* terminate the string */
+ p = strchr(str, ':');
+ if (!p) {
+ goto done;
+ }
+ *p = '\0';
+
+ if (strlen(str) != num) {
+ goto done;
+ }
+
+ str = p + 1;
+
+ dn = ldb_dn_explode(memctx, str);
+ if (dn) {
+ ret = LDB_SUCCESS;
+ }
+
+done:
+ talloc_free(memctx);
+ return ret;
+}
+
+struct schema_syntax_validator {
+ enum schema_internal_syntax type;
+ int (*validate)(struct ldb_val *, int, int);
+};
+
+struct schema_syntax_validator schema_syntax_validators[] = {
+ { SCHEMA_AS_BOOLEAN, schema_validate_boolean },
+ { SCHEMA_AS_INTEGER, schema_validate_integer },
+ { SCHEMA_AS_OCTET_STRING, schema_validate_binary_blob },
+ { SCHEMA_AS_SID, schema_validate_sid },
+ { SCHEMA_AS_OID, schema_validate_oid },
+ { SCHEMA_AS_ENUMERATION, schema_validate_integer },
+ { SCHEMA_AS_NUMERIC_STRING, schema_validate_numeric_string },
+ { SCHEMA_AS_PRINTABLE_STRING, schema_validate_printable_string },
+ { SCHEMA_AS_CASE_IGNORE_STRING, schema_validate_teletext_string },
+ { SCHEMA_AS_IA5_STRING, schema_validate_ia5_string },
+ { SCHEMA_AS_UTC_TIME, schema_validate_utc_time },
+ { SCHEMA_AS_GENERALIZED_TIME, schema_validate_generalized_time },
+ { SCHEMA_AS_CASE_SENSITIVE_STRING, schema_validate_sensitive_string },
+ { SCHEMA_AS_DIRECTORY_STRING, schema_validate_unicode_string },
+ { SCHEMA_AS_LARGE_INTEGER, schema_validate_large_integer },
+ { SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR, schema_validate_object_sd },
+ { SCHEMA_AS_DN, schema_validate_dn },
+ { SCHEMA_AS_DN_BINARY, schema_validate_binary_plus_dn },
+ { SCHEMA_AS_OR_NAME, schema_validate_x400_or_name },
+ { SCHEMA_AS_REPLICA_LINK, schema_validate_binary_blob },
+ { SCHEMA_AS_PRESENTATION_ADDRESS, schema_validate_presentation_address }, /* see rfc1278 ? */
+ { SCHEMA_AS_ACCESS_POINT, schema_validate_x400_access_point },
+ { SCHEMA_AS_DN_STRING, schema_validate_string_plus_dn },
+ { -1, NULL }
+};
+
+int schema_validate(struct ldb_message_element *el,
+ enum schema_internal_syntax type,
+ bool single, int min, int max)
+{
+ struct schema_syntax_validator *v;
+ int i, ret;
+
+ if (single && (el->num_values > 1)) {
+ return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+ }
+
+ for (i = 0; schema_syntax_validators[i].type != 0; i++) {
+ if (schema_syntax_validators[i].type == type)
+ break;
+ }
+ if (schema_syntax_validators[i].type == 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ v = &schema_syntax_validators[i];
+
+ for (i = 0; i < el->num_values; i++) {
+ ret = v->validate(&el->values[i], min, max);
+ }
+
+ return LDB_SUCCESS;
+}
+
+