4 Copyright (C) Simo Sorce 2004-2006
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 * Component: ldb schema module
25 * Description: add schema syntax functionality
31 #include "ldb/include/ldb.h"
32 #include "ldb/include/ldb_errors.h"
33 #include "schema_syntax.h"
35 int map_schema_syntax(uint32_t om_syntax, const char *attr_syntax, const struct ldb_val *om_class, enum schema_internal_syntax *syntax)
43 *syntax = SCHEMA_AS_BOOLEAN;
46 *syntax = SCHEMA_AS_INTEGER;
49 if (strcmp(attr_syntax, "2.5.5.10") == 0) {
50 *syntax = SCHEMA_AS_OCTET_STRING;
53 if (strcmp(attr_syntax, "2.5.5.17") == 0) {
54 *syntax = SCHEMA_AS_SID;
57 ret = LDB_ERR_OPERATIONS_ERROR;
60 *syntax = SCHEMA_AS_OID;
63 *syntax = SCHEMA_AS_ENUMERATION;
66 *syntax = SCHEMA_AS_NUMERIC_STRING;
69 *syntax = SCHEMA_AS_PRINTABLE_STRING;
72 *syntax = SCHEMA_AS_CASE_IGNORE_STRING;
75 *syntax = SCHEMA_AS_IA5_STRING;
78 *syntax = SCHEMA_AS_UTC_TIME;
81 *syntax = SCHEMA_AS_GENERALIZED_TIME;
84 *syntax = SCHEMA_AS_CASE_SENSITIVE_STRING;
87 *syntax = SCHEMA_AS_DIRECTORY_STRING;
90 *syntax = SCHEMA_AS_LARGE_INTEGER;
93 *syntax = SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR;
97 ret = LDB_ERR_OPERATIONS_ERROR;
101 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a\x00", MIN(om_class->length, 10)) == 0) {
102 *syntax = SCHEMA_AS_DN;
105 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b", MIN(om_class->length, 10)) == 0) {
106 *syntax = SCHEMA_AS_DN_BINARY;
109 if (memcmp(om_class->data, "\x56\x06\x01\x02\x05\x0b\x1d\x00\x00\x00", MIN(om_class->length, 10)) == 0) {
110 *syntax = SCHEMA_AS_OR_NAME;
113 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06", MIN(om_class->length, 10)) == 0) {
114 *syntax = SCHEMA_AS_REPLICA_LINK;
117 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c\x00", MIN(om_class->length, 10)) == 0) {
118 *syntax = SCHEMA_AS_PRESENTATION_ADDRESS;
121 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e\x00", MIN(om_class->length, 10)) == 0) {
122 *syntax = SCHEMA_AS_ACCESS_POINT;
125 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c", MIN(om_class->length, 10)) == 0) {
126 *syntax = SCHEMA_AS_DN_STRING;
129 /* not found will error in default: */
131 ret = LDB_ERR_OPERATIONS_ERROR;
137 static int schema_validate_boolean(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
140 if ((strncmp("TRUE", (const char *)val->data, val->length) != 0) &&
141 (strncmp("FALSE", (const char *)val->data, val->length) != 0)) {
142 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
148 static int schema_validate_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
154 value = strtol((const char *)val->data, &endptr, 0);
155 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
156 if (endptr[0] != '\0') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
157 if ((min > INT_MIN) && (value < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
158 if ((max < INT_MAX) && (value > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
163 static int schema_validate_binary_blob(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
165 /* is there anythign we should check in a binary blob ? */
169 static int schema_validate_sid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
171 /* TODO: validate binary form of objectSid */
175 static int schema_validate_oid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
177 if (strspn((const char *)val->data, "0123456789.") != val->length)
178 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
183 static int schema_validate_numeric_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
185 if (strspn((const char *)val->data, "0123456789") != val->length)
186 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
191 static int schema_validate_printable_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
193 /* TODO: find out what constitutes the printable character set */
197 static int schema_validate_teletext_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
199 /* TODO: find out what constitutes the teletext character set */
203 static int schema_validate_ia5_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
205 /* TODO: find out what constitutes the IA5 character set */
209 static int schema_validate_utc_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
211 /* TODO: validate syntax of UTC Time string */
215 static int schema_validate_generalized_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
217 /* TODO: validate syntax of Generalized Time string */
221 /* NOTE: not a single attribute has this syntax in the basic w2k3 schema */
222 static int schema_validate_sensitive_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
224 /* TODO: find out what constitutes a "case sensitive string" */
228 static int schema_validate_unicode_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
230 /* TODO: validate utf8 string */
234 static int schema_validate_large_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
236 /* TODO: validate large integer/interval */
240 static int schema_validate_object_sd(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
242 /* TODO: validate object Security Descriptor */
246 static int schema_validate_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
249 int ret = LDB_SUCCESS;
251 dn = ldb_dn_from_ldb_val(ldb, ldb, val);
252 if ( ! ldb_dn_validate(dn)) {
253 ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
260 static int schema_validate_binary_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
262 int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
269 memctx = talloc_new(NULL);
270 if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
272 str = talloc_strdup(memctx, (const char *)val->data);
274 ret = LDB_ERR_OPERATIONS_ERROR;
277 if (strncasecmp(str, "B:", 2) != 0) {
281 /* point at the number of chars in the string */
282 str = strchr(&str[2], ':');
289 num = strtol(str, &endptr, 0);
290 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
291 if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
292 if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
293 if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
295 /* point at the string */
296 str = strchr(str, ':');
302 /* terminate the string */
303 p = strchr(str, ':');
309 if (strlen(str) != 2*num) {
315 dn = ldb_dn_new(memctx, ldb, str);
316 if (ldb_dn_validate(dn)) {
325 static int schema_validate_x400_or_name(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
327 /* TODO: find out what is the syntax of an X400 OR NAME */
331 static int schema_validate_presentation_address(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
333 /* TODO: find out what is the syntax of a presentation address */
337 static int schema_validate_x400_access_point(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
339 /* TODO: find out what is the syntax of an X400 Access Point */
343 /* NOTE: seem there isn't a single attribute defined like this in the base w2k3 schema */
344 static int schema_validate_string_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
346 int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
353 memctx = talloc_new(NULL);
354 if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
356 str = talloc_strdup(memctx, (const char *)val->data);
358 ret = LDB_ERR_OPERATIONS_ERROR;
361 if (strncasecmp(str, "S:", 2) != 0) {
365 /* point at the number of chars in the string */
366 str = strchr(&str[2], ':');
373 num = strtol(str, &endptr, 0);
374 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
375 if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
376 if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
377 if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
379 /* point at the string */
380 str = strchr(str, ':');
386 /* terminate the string */
387 p = strchr(str, ':');
393 if (strlen(str) != num) {
399 dn = ldb_dn_new(memctx, ldb, str);
400 if (ldb_dn_validate(dn)) {
409 struct schema_syntax_validator {
410 enum schema_internal_syntax type;
411 int (*validate)(struct ldb_context *ldb, struct ldb_val *, int, int);
414 struct schema_syntax_validator schema_syntax_validators[] = {
415 { SCHEMA_AS_BOOLEAN, schema_validate_boolean },
416 { SCHEMA_AS_INTEGER, schema_validate_integer },
417 { SCHEMA_AS_OCTET_STRING, schema_validate_binary_blob },
418 { SCHEMA_AS_SID, schema_validate_sid },
419 { SCHEMA_AS_OID, schema_validate_oid },
420 { SCHEMA_AS_ENUMERATION, schema_validate_integer },
421 { SCHEMA_AS_NUMERIC_STRING, schema_validate_numeric_string },
422 { SCHEMA_AS_PRINTABLE_STRING, schema_validate_printable_string },
423 { SCHEMA_AS_CASE_IGNORE_STRING, schema_validate_teletext_string },
424 { SCHEMA_AS_IA5_STRING, schema_validate_ia5_string },
425 { SCHEMA_AS_UTC_TIME, schema_validate_utc_time },
426 { SCHEMA_AS_GENERALIZED_TIME, schema_validate_generalized_time },
427 { SCHEMA_AS_CASE_SENSITIVE_STRING, schema_validate_sensitive_string },
428 { SCHEMA_AS_DIRECTORY_STRING, schema_validate_unicode_string },
429 { SCHEMA_AS_LARGE_INTEGER, schema_validate_large_integer },
430 { SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR, schema_validate_object_sd },
431 { SCHEMA_AS_DN, schema_validate_dn },
432 { SCHEMA_AS_DN_BINARY, schema_validate_binary_plus_dn },
433 { SCHEMA_AS_OR_NAME, schema_validate_x400_or_name },
434 { SCHEMA_AS_REPLICA_LINK, schema_validate_binary_blob },
435 { SCHEMA_AS_PRESENTATION_ADDRESS, schema_validate_presentation_address }, /* see rfc1278 ? */
436 { SCHEMA_AS_ACCESS_POINT, schema_validate_x400_access_point },
437 { SCHEMA_AS_DN_STRING, schema_validate_string_plus_dn },
441 int schema_validate(struct ldb_context *ldb,
442 struct ldb_message_element *el,
443 enum schema_internal_syntax type,
444 bool single, int min, int max)
446 struct schema_syntax_validator *v;
449 if (single && (el->num_values > 1)) {
450 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
453 for (i = 0; schema_syntax_validators[i].type != 0; i++) {
454 if (schema_syntax_validators[i].type == type)
457 if (schema_syntax_validators[i].type == 0) {
458 return LDB_ERR_OPERATIONS_ERROR;
460 v = &schema_syntax_validators[i];
462 for (i = 0; i < el->num_values; i++) {
463 ret = v->validate(ldb, &el->values[i], min, max);