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
29 * License: GNU GPL v2 or Later
33 #include "ldb/include/ldb.h"
34 #include "ldb/include/ldb_errors.h"
35 #include "schema_syntax.h"
37 int map_schema_syntax(uint32_t om_syntax, const char *attr_syntax, const struct ldb_val *om_class, enum schema_internal_syntax *syntax)
45 *syntax = SCHEMA_AS_BOOLEAN;
48 *syntax = SCHEMA_AS_INTEGER;
51 if (strcmp(attr_syntax, "2.5.5.10") == 0) {
52 *syntax = SCHEMA_AS_OCTET_STRING;
55 if (strcmp(attr_syntax, "2.5.5.17") == 0) {
56 *syntax = SCHEMA_AS_SID;
59 ret = LDB_ERR_OPERATIONS_ERROR;
62 *syntax = SCHEMA_AS_OID;
65 *syntax = SCHEMA_AS_ENUMERATION;
68 *syntax = SCHEMA_AS_NUMERIC_STRING;
71 *syntax = SCHEMA_AS_PRINTABLE_STRING;
74 *syntax = SCHEMA_AS_CASE_IGNORE_STRING;
77 *syntax = SCHEMA_AS_IA5_STRING;
80 *syntax = SCHEMA_AS_UTC_TIME;
83 *syntax = SCHEMA_AS_GENERALIZED_TIME;
86 *syntax = SCHEMA_AS_CASE_SENSITIVE_STRING;
89 *syntax = SCHEMA_AS_DIRECTORY_STRING;
92 *syntax = SCHEMA_AS_LARGE_INTEGER;
95 *syntax = SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR;
99 ret = LDB_ERR_OPERATIONS_ERROR;
103 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a\x00", MIN(om_class->length, 10)) == 0) {
104 *syntax = SCHEMA_AS_DN;
107 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b", MIN(om_class->length, 10)) == 0) {
108 *syntax = SCHEMA_AS_DN_BINARY;
111 if (memcmp(om_class->data, "\x56\x06\x01\x02\x05\x0b\x1d\x00\x00\x00", MIN(om_class->length, 10)) == 0) {
112 *syntax = SCHEMA_AS_OR_NAME;
115 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06", MIN(om_class->length, 10)) == 0) {
116 *syntax = SCHEMA_AS_REPLICA_LINK;
119 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c\x00", MIN(om_class->length, 10)) == 0) {
120 *syntax = SCHEMA_AS_PRESENTATION_ADDRESS;
123 if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e\x00", MIN(om_class->length, 10)) == 0) {
124 *syntax = SCHEMA_AS_ACCESS_POINT;
127 if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c", MIN(om_class->length, 10)) == 0) {
128 *syntax = SCHEMA_AS_DN_STRING;
131 /* not found will error in default: */
133 ret = LDB_ERR_OPERATIONS_ERROR;
139 static int schema_validate_boolean(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
142 if ((strncmp("TRUE", (const char *)val->data, val->length) != 0) &&
143 (strncmp("FALSE", (const char *)val->data, val->length) != 0)) {
144 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
150 static int schema_validate_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
156 value = strtol((const char *)val->data, &endptr, 0);
157 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
158 if (endptr[0] != '\0') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
159 if ((min > INT_MIN) && (value < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
160 if ((max < INT_MAX) && (value > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
165 static int schema_validate_binary_blob(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
167 /* is there anythign we should check in a binary blob ? */
171 static int schema_validate_sid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
173 /* TODO: validate binary form of objectSid */
177 static int schema_validate_oid(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
179 if (strspn((const char *)val->data, "0123456789.") != val->length)
180 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
185 static int schema_validate_numeric_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
187 if (strspn((const char *)val->data, "0123456789") != val->length)
188 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
193 static int schema_validate_printable_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
195 /* TODO: find out what constitutes the printable character set */
199 static int schema_validate_teletext_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
201 /* TODO: find out what constitutes the teletext character set */
205 static int schema_validate_ia5_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
207 /* TODO: find out what constitutes the IA5 character set */
211 static int schema_validate_utc_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
213 /* TODO: validate syntax of UTC Time string */
217 static int schema_validate_generalized_time(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
219 /* TODO: validate syntax of Generalized Time string */
223 /* NOTE: not a single attribute has this syntax in the basic w2k3 schema */
224 static int schema_validate_sensitive_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
226 /* TODO: find out what constitutes a "case sensitive string" */
230 static int schema_validate_unicode_string(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
232 /* TODO: validate utf8 string */
236 static int schema_validate_large_integer(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
238 /* TODO: validate large integer/interval */
242 static int schema_validate_object_sd(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
244 /* TODO: validate object Security Descriptor */
248 static int schema_validate_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
251 int ret = LDB_SUCCESS;
253 dn = ldb_dn_new(ldb, ldb, (const char *)val->data);
254 if ( ! ldb_dn_validate(dn)) {
255 ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
262 static int schema_validate_binary_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
264 int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
271 memctx = talloc_new(NULL);
272 if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
274 str = talloc_strdup(memctx, (const char *)val->data);
276 ret = LDB_ERR_OPERATIONS_ERROR;
279 if (strncasecmp(str, "B:", 2) != 0) {
283 /* point at the number of chars in the string */
284 str = strchr(&str[2], ':');
291 num = strtol(str, &endptr, 0);
292 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
293 if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
294 if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
295 if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
297 /* point at the string */
298 str = strchr(str, ':');
304 /* terminate the string */
305 p = strchr(str, ':');
311 if (strlen(str) != 2*num) {
317 dn = ldb_dn_new(memctx, ldb, str);
318 if (ldb_dn_validate(dn)) {
327 static int schema_validate_x400_or_name(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
329 /* TODO: find out what is the syntax of an X400 OR NAME */
333 static int schema_validate_presentation_address(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
335 /* TODO: find out what is the syntax of a presentation address */
339 static int schema_validate_x400_access_point(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
341 /* TODO: find out what is the syntax of an X400 Access Point */
345 /* NOTE: seem there isn't a single attribute defined like this in the base w2k3 schema */
346 static int schema_validate_string_plus_dn(struct ldb_context *ldb, struct ldb_val *val, int min, int max)
348 int ret = LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
355 memctx = talloc_new(NULL);
356 if (!memctx) return LDB_ERR_OPERATIONS_ERROR;
358 str = talloc_strdup(memctx, (const char *)val->data);
360 ret = LDB_ERR_OPERATIONS_ERROR;
363 if (strncasecmp(str, "S:", 2) != 0) {
367 /* point at the number of chars in the string */
368 str = strchr(&str[2], ':');
375 num = strtol(str, &endptr, 0);
376 if (errno) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
377 if (endptr[0] != ':') return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
378 if ((min > INT_MIN) && (num < min)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
379 if ((max < INT_MAX) && (num > max)) return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
381 /* point at the string */
382 str = strchr(str, ':');
388 /* terminate the string */
389 p = strchr(str, ':');
395 if (strlen(str) != num) {
401 dn = ldb_dn_new(memctx, ldb, str);
402 if (ldb_dn_validate(dn)) {
411 struct schema_syntax_validator {
412 enum schema_internal_syntax type;
413 int (*validate)(struct ldb_context *ldb, struct ldb_val *, int, int);
416 struct schema_syntax_validator schema_syntax_validators[] = {
417 { SCHEMA_AS_BOOLEAN, schema_validate_boolean },
418 { SCHEMA_AS_INTEGER, schema_validate_integer },
419 { SCHEMA_AS_OCTET_STRING, schema_validate_binary_blob },
420 { SCHEMA_AS_SID, schema_validate_sid },
421 { SCHEMA_AS_OID, schema_validate_oid },
422 { SCHEMA_AS_ENUMERATION, schema_validate_integer },
423 { SCHEMA_AS_NUMERIC_STRING, schema_validate_numeric_string },
424 { SCHEMA_AS_PRINTABLE_STRING, schema_validate_printable_string },
425 { SCHEMA_AS_CASE_IGNORE_STRING, schema_validate_teletext_string },
426 { SCHEMA_AS_IA5_STRING, schema_validate_ia5_string },
427 { SCHEMA_AS_UTC_TIME, schema_validate_utc_time },
428 { SCHEMA_AS_GENERALIZED_TIME, schema_validate_generalized_time },
429 { SCHEMA_AS_CASE_SENSITIVE_STRING, schema_validate_sensitive_string },
430 { SCHEMA_AS_DIRECTORY_STRING, schema_validate_unicode_string },
431 { SCHEMA_AS_LARGE_INTEGER, schema_validate_large_integer },
432 { SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR, schema_validate_object_sd },
433 { SCHEMA_AS_DN, schema_validate_dn },
434 { SCHEMA_AS_DN_BINARY, schema_validate_binary_plus_dn },
435 { SCHEMA_AS_OR_NAME, schema_validate_x400_or_name },
436 { SCHEMA_AS_REPLICA_LINK, schema_validate_binary_blob },
437 { SCHEMA_AS_PRESENTATION_ADDRESS, schema_validate_presentation_address }, /* see rfc1278 ? */
438 { SCHEMA_AS_ACCESS_POINT, schema_validate_x400_access_point },
439 { SCHEMA_AS_DN_STRING, schema_validate_string_plus_dn },
443 int schema_validate(struct ldb_context *ldb,
444 struct ldb_message_element *el,
445 enum schema_internal_syntax type,
446 bool single, int min, int max)
448 struct schema_syntax_validator *v;
451 if (single && (el->num_values > 1)) {
452 return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
455 for (i = 0; schema_syntax_validators[i].type != 0; i++) {
456 if (schema_syntax_validators[i].type == type)
459 if (schema_syntax_validators[i].type == 0) {
460 return LDB_ERR_OPERATIONS_ERROR;
462 v = &schema_syntax_validators[i];
464 for (i = 0; i < el->num_values; i++) {
465 ret = v->validate(ldb, &el->values[i], min, max);