s4-dsdb/schema_syntax: Separate validation for numericoid OID values
authorKamen Mazdrashki <kamenim@samba.org>
Wed, 20 Oct 2010 10:49:46 +0000 (13:49 +0300)
committerKamen Mazdrashki <kamenim@samba.org>
Thu, 21 Oct 2010 23:32:26 +0000 (23:32 +0000)
This implementation doesn't use prefixMap/Schema to validate
numericoid OIDs. We may not have this OID yet, so I see no point
checking schema for if we have it.

Side effect of using prefixMap/Schema for validating numericoids
is that we mistakenly add the OID to the prefixMap.
This led to a corrupted prefixMap in LDB.

Autobuild-User: Kamen Mazdrashki <kamenim@samba.org>
Autobuild-Date: Thu Oct 21 23:32:26 UTC 2010 on sn-devel-104

source4/dsdb/schema/schema_syntax.c

index db53aea612a0303659abe1ed1c070430343097de..d6e45273af967a0b39435cd73994377c3ed6c726 100644 (file)
@@ -30,6 +30,7 @@
 #include "system/time.h"
 #include "../lib/util/charset/charset.h"
 #include "librpc/ndr/libndr.h"
+#include "../lib/util/asn1.h"
 
 /**
  * Initialize dsdb_syntax_ctx with default values
@@ -1303,6 +1304,44 @@ static WERROR dsdb_syntax_OID_ldb_to_drsuapi(const struct dsdb_syntax_ctx *ctx,
        return _dsdb_syntax_auto_OID_ldb_to_drsuapi(ctx, attr, in, mem_ctx, out);
 }
 
+static WERROR _dsdb_syntax_OID_validate_numericoid(const struct dsdb_syntax_ctx *ctx,
+                                                  const struct dsdb_attribute *attr,
+                                                  const struct ldb_message_element *in)
+{
+       unsigned int i;
+       TALLOC_CTX *tmp_ctx;
+
+       tmp_ctx = talloc_new(ctx->ldb);
+       W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+
+       for (i=0; i < in->num_values; i++) {
+               DATA_BLOB blob;
+               const char *oid_out;
+               const char *oid = (const char*)in->values[i].data;
+
+               if (!ber_write_OID_String(tmp_ctx, &blob, oid)) {
+                       DEBUG(0,("ber_write_OID_String() failed for %s\n", oid));
+                       talloc_free(tmp_ctx);
+                       return WERR_INVALID_PARAMETER;
+               }
+
+               if (!ber_read_OID_String(tmp_ctx, blob, &oid_out)) {
+                       DEBUG(0,("ber_read_OID_String() failed for %s\n",
+                                hex_encode_talloc(tmp_ctx, blob.data, blob.length)));
+                       talloc_free(tmp_ctx);
+                       return WERR_INVALID_PARAMETER;
+               }
+
+               if (strcmp(oid, oid_out) != 0) {
+                       talloc_free(tmp_ctx);
+                       return WERR_INVALID_PARAMETER;
+               }
+       }
+
+       talloc_free(tmp_ctx);
+       return WERR_OK;
+}
+
 static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
                                           const struct dsdb_attribute *attr,
                                           const struct ldb_message_element *in)
@@ -1316,14 +1355,19 @@ static WERROR dsdb_syntax_OID_validate_ldb(const struct dsdb_syntax_ctx *ctx,
                return WERR_FOOBAR;
        }
 
+       switch (attr->attributeID_id) {
+       case DRSUAPI_ATTRIBUTE_governsID:
+       case DRSUAPI_ATTRIBUTE_attributeID:
+       case DRSUAPI_ATTRIBUTE_attributeSyntax:
+               return _dsdb_syntax_OID_validate_numericoid(ctx, attr, in);
+       }
+
        /*
         * TODO: optimize and verify this code
         */
 
        tmp_ctx = talloc_new(ctx->ldb);
-       if (tmp_ctx == NULL) {
-               return WERR_NOMEM;
-       }
+       W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
        status = dsdb_syntax_OID_ldb_to_drsuapi(ctx,
                                                attr,