Convert some more files to GPLv3.
[jra/samba/.git] / source4 / dsdb / samdb / ldb_modules / schema.c
index 95330e7e8cc11c60b688a3ce2ae7afa645b76a2a..f2c4d383051dfe48e33743a5fd2958772616d1ff 100644 (file)
@@ -5,7 +5,7 @@
 
    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
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
    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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 /*
@@ -26,8 +25,6 @@
  *  Description: add schema check functionality
  *
  *  Author: Simo Sorce
- *
- *  License: GNU GPL v2 or Later
  */
 
 #include "includes.h"
@@ -234,108 +231,6 @@ struct schema_attribute **schema_get_attrs_list(struct ldb_module *module,
        return list;
 }
 
-static int map_schema_syntax(uint32_t om_syntax, const char *attr_syntax, const struct ldb_val *om_class, enum schema_internal_syntax *syntax)
-{
-       int ret;
-
-       ret = LDB_SUCCESS;
-
-       switch(om_syntax) {
-       case 1:
-               *syntax = SCHEMA_AS_BOOLEAN;
-               break;
-       case 2:
-               *syntax = SCHEMA_AS_INTEGER;
-               break;
-       case 4:
-               if (strcmp(attr_syntax, "2.5.5.10") == 0) {
-                       *syntax = SCHEMA_AS_OCTET_STRING;
-                       break;
-               }
-               if (strcmp(attr_syntax, "2.5.5.17") == 0) {
-                       *syntax = SCHEMA_AS_SID;
-                       break;
-               }
-               ret = LDB_ERR_OPERATIONS_ERROR;
-               break;
-       case 6:
-               *syntax = SCHEMA_AS_OID;
-               break;
-       case 10:
-               *syntax = SCHEMA_AS_ENUMERATION;
-               break;
-       case 18:
-               *syntax = SCHEMA_AS_NUMERIC_STRING;
-               break;
-       case 19:
-               *syntax = SCHEMA_AS_PRINTABLE_STRING;
-               break;
-       case 20:
-               *syntax = SCHEMA_AS_CASE_IGNORE_STRING;
-               break;
-       case 22:
-               *syntax = SCHEMA_AS_IA5_STRING;
-               break;
-       case 23:
-               *syntax = SCHEMA_AS_UTC_TIME;
-               break;
-       case 24:
-               *syntax = SCHEMA_AS_GENERALIZED_TIME;
-               break;
-       case 27:
-               *syntax = SCHEMA_AS_CASE_SENSITIVE_STRING;
-               break;
-       case 64:
-               *syntax = SCHEMA_AS_DIRECTORY_STRING;
-               break;
-       case 65:
-               *syntax = SCHEMA_AS_LARGE_INTEGER;
-               break;
-       case 66:
-               *syntax = SCHEMA_AS_OBJECT_SECURITY_DESCRIPTOR;
-               break;
-       case 127:
-               if (!om_class) {
-                       ret = LDB_ERR_OPERATIONS_ERROR;
-                       break;
-               }
-               
-               if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a\x00", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_DN;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_DN_BINARY;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x56\x06\x01\x02\x05\x0b\x1d\x00\x00\x00", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_OR_NAME;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x06", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_REPLICA_LINK;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x5c\x00", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_PRESENTATION_ADDRESS;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x2b\x0c\x02\x87\x73\x1c\x00\x85\x3e\x00", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_ACCESS_POINT;
-                       break;
-               }
-               if (memcmp(om_class->data, "\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c", MIN(om_class->length, 10)) == 0) {
-                       *syntax = SCHEMA_AS_DN_STRING;
-                       break;
-               }
-               /* not found will error in default: */
-       default:
-               ret = LDB_ERR_OPERATIONS_ERROR;
-       }
-
-       return ret;
-}
-
 static int schema_init_attrs(struct ldb_module *module, struct schema_private_data *data)
 {
        static const char *schema_attrs[] = {   "attributeID",
@@ -422,7 +317,7 @@ static int schema_init_attrs(struct ldb_module *module, struct schema_private_da
                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);
+               data->attrs[i]->isdefunct = ldb_msg_find_attr_as_bool(res->msgs[i], "isDefunct", false);
        }
 
 done:
@@ -432,10 +327,10 @@ done:
 
 static int schema_init_classes(struct ldb_module *module, struct schema_private_data *data)
 {
-       static const char *schema_attrs[] = {   "governsID",
+       const char *schema_attrs[] = {  "governsID",
                                                "lDAPDisplayName",
                                                "objectClassCategory",
-                                               "defaultObjectCategory"
+                                               "defaultObjectCategory",
                                                "systemOnly",
                                                "systemFlag",
                                                "isDefunct",
@@ -496,13 +391,13 @@ static int schema_init_classes(struct ldb_module *module, struct schema_private_
                data->class[i]->defobjcat = talloc_strdup(data->class[i],
                                                ldb_msg_find_attr_as_string(res->msgs[i],
                                                                        "defaultObjectCategory", NULL));
-               SCHEMA_CHECK_VALUE(data->class[i]->defobjcat, NULL, module);
-
+/*             SCHEMA_CHECK_VALUE(data->class[i]->defobjcat, NULL, module);
+*/
                /* the following attributes are all optional */
 
-               data->class[i]->systemOnly = ldb_msg_find_attr_as_bool(res->msgs[i], "systemOnly", False);
+               data->class[i]->systemOnly = ldb_msg_find_attr_as_bool(res->msgs[i], "systemOnly", false);
                data->class[i]->systemflag = ldb_msg_find_attr_as_int(res->msgs[i], "systemFlag", 0);
-               data->class[i]->isdefunct = ldb_msg_find_attr_as_bool(res->msgs[i], "isDefunct", False);
+               data->class[i]->isdefunct = ldb_msg_find_attr_as_bool(res->msgs[i], "isDefunct", false);
 
                /* attributes are loaded first, so we can just go an query the attributes repo */
                
@@ -626,11 +521,6 @@ static int schema_add_check_parent(struct ldb_context *ldb, void *context, struc
 {
        struct schema_context *sctx;
 
-       if (!context || !ares) {
-               ldb_set_errstring(ldb, "NULL Context or Result in callback");
-               return LDB_ERR_OPERATIONS_ERROR;
-       }
-
        sctx = talloc_get_type(context, struct schema_context);
 
        /* we are interested only in the single reply (base search) we receive here */
@@ -650,7 +540,7 @@ static int schema_add_check_parent(struct ldb_context *ldb, void *context, struc
 
 static int schema_add_build_parent_req(struct schema_context *sctx)
 {
-       static const char * const parent_attrs[] = { "objectClass", NULL };
+       const char * const parent_attrs[] = { "objectClass", NULL };
        int ret;
 
        sctx->parent_req = talloc_zero(sctx, struct ldb_request);
@@ -662,7 +552,7 @@ static int schema_add_build_parent_req(struct schema_context *sctx)
        sctx->parent_req->operation = LDB_SEARCH;
        sctx->parent_req->op.search.scope = LDB_SCOPE_BASE;
        sctx->parent_req->op.search.base = ldb_dn_get_parent(sctx->parent_req, sctx->orig_req->op.add.message->dn);
-       sctx->parent_req->op.search.tree = ldb_parse_tree(sctx->module->ldb, "(objectClass=*)");
+       sctx->parent_req->op.search.tree = ldb_parse_tree(sctx->parent_req, "(objectClass=*)");
        sctx->parent_req->op.search.attrs = parent_attrs;
        sctx->parent_req->controls = NULL;
        sctx->parent_req->context = sctx;
@@ -986,7 +876,6 @@ static int schema_add_build_down_req(struct schema_context *sctx)
 {
        struct schema_class_dlist *temp;
        struct ldb_message *msg;
-       char *oc;
        int ret;
 
        sctx->down_req = talloc(sctx, struct ldb_request);
@@ -1004,7 +893,7 @@ static int schema_add_build_down_req(struct schema_context *sctx)
 
        /* rebuild the objectclass list */
        ldb_msg_remove_attr(msg, "objectClass");
-       ret = ldb_msg_add_empty(msg, "objectClass", 0);
+       ret = ldb_msg_add_empty(msg, "objectClass", 0, NULL);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
@@ -1028,14 +917,35 @@ static int schema_add_build_down_req(struct schema_context *sctx)
                if (!temp->next) break;
                if (temp->next->role != SCHEMA_CT_STRUCTURAL) break;
        }
-       oc = talloc_strdup(msg, temp->class->defobjcat);
+/*     oc = talloc_strdup(msg, temp->class->defobjcat);
        ret = ldb_msg_add_string(msg, "objectCategory", oc);
-
+*/
        sctx->down_req->op.add.message = msg;
 
        return LDB_SUCCESS;
 }
 
+static int schema_check_attributes_syntax(struct schema_context *sctx)
+{
+       struct ldb_message *msg;
+       struct schema_attribute *attr;
+       int i, ret;
+
+       msg = sctx->orig_req->op.add.message;
+       for (i = 0; i < msg->num_elements; i++) {
+               attr = schema_store_find(sctx->data->attrs_store, msg->elements[i].name);
+               if (attr == NULL) {
+                       return LDB_ERR_NO_SUCH_ATTRIBUTE;
+               }
+               ret = schema_validate(sctx->module->ldb, &msg->elements[i], attr->syntax, attr->single, attr->min, attr->max);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+       }
+
+       return LDB_SUCCESS;
+}
+
 static int schema_add_continue(struct ldb_handle *h)
 {
        struct schema_context *sctx;
@@ -1077,12 +987,11 @@ static int schema_add_continue(struct ldb_handle *h)
                }
 
                /* check attributes syntax */
-               /*
+               
                ret = schema_check_attributes_syntax(sctx);
                if (ret != LDB_SUCCESS) {
                        break;
                }
-               */
 
                ret = schema_add_build_down_req(sctx);
                if (ret != LDB_SUCCESS) {
@@ -1250,20 +1159,26 @@ static int schema_init(struct ldb_module *module)
        struct ldb_result *res;
        int ret;
 
-       /* need to let the partiorion module to register first */
+       /* need to let the partition module to register first */
        ret = ldb_next_init(module);
        if (ret != LDB_SUCCESS) {
                return ret;
        }
 
-       data = talloc_zero(module, struct schema_private_data);
+       data = ldb_get_opaque(module->ldb, "schema_instance");
+       if (data) {
+               module->private_data = data;
+               return LDB_SUCCESS;
+       }
+
+       data = talloc_zero(module->ldb, struct schema_private_data);
        if (data == NULL) {
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
        /* find the schema partition */
        ret = ldb_search(module->ldb,
-                        ldb_dn_new(module),
+                        ldb_dn_new(module, module->ldb, NULL),
                         LDB_SCOPE_BASE,
                         "(objectClass=*)",
                         schema_attrs,
@@ -1276,7 +1191,7 @@ static int schema_init(struct ldb_module *module)
                return LDB_ERR_OPERATIONS_ERROR;
        }
 
-       data->schema_dn = ldb_msg_find_attr_as_dn(data, res->msgs[0], "schemaNamingContext");
+       data->schema_dn = ldb_msg_find_attr_as_dn(module->ldb, data, res->msgs[0], "schemaNamingContext");
        if (data->schema_dn == NULL) {
                /* FIXME: return a clear error string */
                talloc_free(data);
@@ -1299,10 +1214,12 @@ static int schema_init(struct ldb_module *module)
        }
 
        module->private_data = data;
+       ldb_set_opaque(module->ldb, "schema_instance", data);
+
        return LDB_SUCCESS;
 }
 
-static const struct ldb_module_ops schema_ops = {
+_PUBLIC_ const struct ldb_module_ops ldb_schema_module_ops = {
        .name          = "schema",
        .init_context  = schema_init,
        .add           = schema_add,
@@ -1311,8 +1228,3 @@ static const struct ldb_module_ops schema_ops = {
        .rename        = schema_rename,
        .wait          = schema_wait
 };
-
-int ldb_schema_init(void)
-{
-       return ldb_register_module(&schema_ops);
-}