diff options
Diffstat (limited to 'source4/dsdb/samdb/ldb_modules/schema_syntax.c')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_syntax.c | 373 |
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; +} + + |