diff options
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/config.mk | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema.c | 31 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_syntax.c | 373 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/schema_syntax.h | 64 |
4 files changed, 441 insertions, 29 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk index a24703c5b6..1e3b793629 100644 --- a/source4/dsdb/samdb/ldb_modules/config.mk +++ b/source4/dsdb/samdb/ldb_modules/config.mk @@ -130,7 +130,7 @@ OBJ_FILES = \ SUBSYSTEM = ldb INIT_FUNCTION = ldb_schema_init OBJ_FILES = \ - schema.o + schema.o schema_syntax.o # # End MODULE ldb_schema ################################################ diff --git a/source4/dsdb/samdb/ldb_modules/schema.c b/source4/dsdb/samdb/ldb_modules/schema.c index e498fa987e..36b7916e95 100644 --- a/source4/dsdb/samdb/ldb_modules/schema.c +++ b/source4/dsdb/samdb/ldb_modules/schema.c @@ -35,38 +35,13 @@ #include "ldb/include/ldb_errors.h" #include "ldb/include/ldb_private.h" #include "lib/util/dlinklist.h" +#include "schema_syntax.h" /* Syntax-Table see ldap_server/devdocs/AD-syntaxes.txt */ -enum schema_internal_syntax { - SCHEMA_AS_BOOLEAN, - SCHEMA_AS_INTEGER, - SCHEMA_AS_OCTET_STRING, - SCHEMA_AS_SID, - SCHEMA_AS_OID, - SCHEMA_AS_ENUMERATION, - SCHEMA_AS_NUMERIC_STRING, - SCHEMA_AS_PRINTABLE_STRING, - SCHEMA_AS_CASE_IGNORE_STRING, - SCHEMA_AS_IA5_STRING, - SCHEMA_AS_UTC_TIME, - SCHEMA_AS_GENERALIZED_TIME, - SCHEMA_AS_CASE_SENSITIVE_STRING, - SCHEMA_AS_DIRECTORY_STRING, - SCHEMA_AS_LARGE_INTEGER, - SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR, - SCHEMA_AS_DN, - SCHEMA_AS_DN_BINARY, - SCHEMA_AS_OR_NAME, - SCHEMA_AS_REPLICA_LINK, - SCHEMA_AS_PRESENTATION_ADDRESS, - SCHEMA_AS_ACCESS_POINT, - SCHEMA_AS_DN_STRING -}; - enum schema_class_type { SCHEMA_CT_88 = 0, SCHEMA_CT_STRUCTURAL = 1, @@ -443,8 +418,8 @@ static int schema_init_attrs(struct ldb_module *module, struct schema_private_da } /* the following are optional */ - data->attrs[i]->min = ldb_msg_find_attr_as_int(res->msgs[i], "rangeLower", -1); - data->attrs[i]->max = ldb_msg_find_attr_as_int(res->msgs[i], "rangeUpper", -1); + data->attrs[i]->min = ldb_msg_find_attr_as_int(res->msgs[i], "rangeLower", INT_MIN); + data->attrs[i]->max = ldb_msg_find_attr_as_int(res->msgs[i], "rangeUpper", INT_MAX); data->attrs[i]->systemflag = ldb_msg_find_attr_as_int(res->msgs[i], "systemFlag", 0); data->attrs[i]->searchflag = ldb_msg_find_attr_as_int(res->msgs[i], "searchFlag", 0); data->attrs[i]->isdefunct = ldb_msg_find_attr_as_bool(res->msgs[i], "isDefunct", False); 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; +} + + diff --git a/source4/dsdb/samdb/ldb_modules/schema_syntax.h b/source4/dsdb/samdb/ldb_modules/schema_syntax.h new file mode 100644 index 0000000000..1974c10b99 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/schema_syntax.h @@ -0,0 +1,64 @@ +/* + 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 + */ + + +/* Syntax-Table + + see ldap_server/devdocs/AD-syntaxes.txt +*/ + +enum schema_internal_syntax { + SCHEMA_AS_BOOLEAN = 1, + SCHEMA_AS_INTEGER = 2, + SCHEMA_AS_OCTET_STRING = 3, + SCHEMA_AS_SID = 4, + SCHEMA_AS_OID = 5, + SCHEMA_AS_ENUMERATION = 6, + SCHEMA_AS_NUMERIC_STRING = 7, + SCHEMA_AS_PRINTABLE_STRING = 8, + SCHEMA_AS_CASE_IGNORE_STRING = 9, + SCHEMA_AS_IA5_STRING = 10, + SCHEMA_AS_UTC_TIME = 11, + SCHEMA_AS_GENERALIZED_TIME = 12, + SCHEMA_AS_CASE_SENSITIVE_STRING = 13, + SCHEMA_AS_DIRECTORY_STRING = 14, + SCHEMA_AS_LARGE_INTEGER = 15, + SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR = 16, + SCHEMA_AS_DN = 17, + SCHEMA_AS_DN_BINARY = 18, + SCHEMA_AS_OR_NAME = 19, + SCHEMA_AS_REPLICA_LINK = 20, + SCHEMA_AS_PRESENTATION_ADDRESS = 21, + SCHEMA_AS_ACCESS_POINT = 22, + SCHEMA_AS_DN_STRING = 23 +}; + |