s4-dsdb: add auto-normalisation of attributes
authorAndrew Tridgell <tridge@samba.org>
Tue, 9 Aug 2011 04:41:20 +0000 (14:41 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 9 Aug 2011 09:56:23 +0000 (11:56 +0200)
this auto-normalises some attributes when they are added/modified. The
list that we auto-normalise is currently:

Boolean
INT32
INTEGER
UTC_TIME

This fixes a problem with groupType being stored in an unnormalised
form

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/dsdb/samdb/ldb_modules/objectclass_attrs.c
source4/dsdb/schema/schema.h
source4/dsdb/schema/schema_syntax.c

index 4525cf3dddbdeffce71f8a795e2d1b53a08eb4c4..9893adae93752c353ac976c163acd428d0586dad 100644 (file)
@@ -88,6 +88,45 @@ static int oc_validate_dsheuristics(struct ldb_message_element *el)
        return LDB_SUCCESS;
 }
 
+/*
+  auto normalise values on input
+ */
+static int oc_auto_normalise(struct ldb_context *ldb, const struct dsdb_attribute *attr,
+                            struct ldb_message *msg, struct ldb_message_element *el)
+{
+       int i;
+       bool values_copied = false;
+
+       for (i=0; i<el->num_values; i++) {
+               struct ldb_val v;
+               int ret;
+               ret = attr->ldb_schema_attribute->syntax->canonicalise_fn(ldb, el->values, &el->values[i], &v);
+               if (ret != LDB_SUCCESS) {
+                       return ret;
+               }
+               if (data_blob_cmp(&v, &el->values[i]) == 0) {
+                       /* no need to replace it */
+                       talloc_free(v.data);
+                       continue;
+               }
+
+               /* we need to copy the values array on the first change */
+               if (!values_copied) {
+                       struct ldb_val *v2;
+                       v2 = talloc_array(msg->elements, struct ldb_val, el->num_values);
+                       if (v2 == NULL) {
+                               return ldb_oom(ldb);
+                       }
+                       memcpy(v2, el->values, sizeof(struct ldb_val) * el->num_values);
+                       el->values = v2;
+                       values_copied = true;
+               }
+
+               el->values[i] = v;
+       }
+       return LDB_SUCCESS;
+}
+
 static int attr_handler(struct oc_context *ac)
 {
        struct ldb_context *ldb;
@@ -174,6 +213,14 @@ static int attr_handler(struct oc_context *ac)
                        }
                }
 
+               /* auto normalise some attribute values */
+               if (attr->syntax->auto_normalise) {
+                       ret = oc_auto_normalise(ldb, attr, msg, &msg->elements[i]);
+                       if (ret != LDB_SUCCESS) {
+                               return ret;
+                       }
+               }
+
                /* Substitute the attribute name to match in case */
                msg->elements[i].name = attr->lDAPDisplayName;
        }
index 13cc31ca879b40712e14c6f45a71db23ac354b3f..58cf82b2973adb915467137af7eb85b52beb7ab7 100644 (file)
@@ -73,6 +73,7 @@ struct dsdb_syntax {
        WERROR (*validate_ldb)(const struct dsdb_syntax_ctx *ctx,
                               const struct dsdb_attribute *attr,
                               const struct ldb_message_element *in);
+       bool auto_normalise;
 };
 
 struct dsdb_attribute {
index d443c009af3dc597272dccd4c8dc7b03347b1982..501ab3adedbb28446900daecf4848f37e9a2de58 100644 (file)
@@ -2365,7 +2365,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
                .validate_ldb           = dsdb_syntax_BOOL_validate_ldb,
                .equality               = "booleanMatch",
-               .comment                = "Boolean"
+               .comment                = "Boolean",
+               .auto_normalise         = true
        },{
                .name                   = "Integer",
                .ldap_oid               = LDB_SYNTAX_INTEGER,
@@ -2376,7 +2377,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
                .equality               = "integerMatch",
                .comment                = "Integer",
-               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32,
+               .auto_normalise         = true
        },{
                .name                   = "String(Octet)",
                .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
@@ -2417,7 +2419,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
                .validate_ldb           = dsdb_syntax_INT32_validate_ldb,
-               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32,
+               .auto_normalise         = true
        },{
        /* not used in w2k3 forest */
                .name                   = "String(Numeric)",
@@ -2473,6 +2476,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .validate_ldb           = dsdb_syntax_NTTIME_UTC_validate_ldb,
                .equality               = "generalizedTimeMatch",
                .comment                = "UTC Time",
+               .auto_normalise         = true
        },{
                .name                   = "String(Generalized-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
@@ -2484,6 +2488,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .equality               = "generalizedTimeMatch",
                .comment                = "Generalized Time",
                .ldb_syntax             = LDB_SYNTAX_UTC_TIME,
+               .auto_normalise         = true
        },{
        /* not used in w2k3 schema */
                .name                   = "String(Case Sensitive)",
@@ -2522,6 +2527,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .equality               = "integerMatch",
                .comment                = "Large Integer",
                .ldb_syntax             = LDB_SYNTAX_INTEGER,
+               .auto_normalise         = true
        },{
                .name                   = "String(NT-Sec-Desc)",
                .ldap_oid               = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,