ldb: activating <= and >= indexing for integers
authorAaron Haslett <aaronhaslett@catalyst.net.nz>
Thu, 14 Mar 2019 05:05:23 +0000 (18:05 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Mon, 8 Apr 2019 02:07:23 +0000 (02:07 +0000)
Activating <= and >= mdb indexing in samba for int32 and int64 attributes by:
1. Adding index_format_fn to LDB_SYNTAX_SAMBA_INT32 in ldb_samba
2. Cloning the 64bit LDB_SYNTAX_INTEGER type as LDB_SYNTAX_ORDERED_INTEGER
3. Adding index_format_fn to the new type
4. Modifying LargeInteger use the new type in samba schema
5. Bumping the index version to trigger reindexing

Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>

Signed-off-by: Aaron Haslett <aaronhaslett@catalyst.net.nz>
Signed-off-by: Garming Sam <garming@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb-samba/ldif_handlers.c
lib/ldb/common/attrib_handlers.c
lib/ldb/include/ldb.h
lib/ldb/pyldb.c
source4/dsdb/schema/schema_set.c
source4/dsdb/schema/schema_syntax.c

index d38cdd0c9a32d7c2c91b0a0a9dad57b264f7dc29..bd8b63c42ed98c96feb491601c5ba4c5d99792ad 100644 (file)
@@ -835,6 +835,50 @@ static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
        return 0;
 }
 
+/* Lexicographically sorted representation for a 32-bit integer */
+static int ldif_index_format_int32(struct ldb_context *ldb,
+                                   void *mem_ctx,
+                                   const struct ldb_val *in,
+                                   struct ldb_val *out)
+{
+       int32_t i;
+       int ret;
+       char prefix;
+       size_t len;
+
+       ret = val_to_int32(in, &i);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       if (i < 0) {
+               prefix = 'n';
+               i = INT32_MAX + i + 1;
+       } else if (i > 0) {
+               prefix = 'p';
+       } else {
+               prefix = 'o';
+       }
+
+       out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%010ld", prefix, (long)i);
+       if (out->data == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       len = talloc_array_length(out->data) - 1;
+       if (len != 11) {
+               ldb_debug(ldb, LDB_DEBUG_ERROR,
+                         __location__ ": expected index format str %s to"
+                         " have length 11 but got %zu",
+                         (char*)out->data, len);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       out->length = 11;
+       return 0;
+}
+
 /* Comparison of two 32-bit integers */
 static int ldif_comparison_int32(struct ldb_context *ldb, void *mem_ctx,
                                 const struct ldb_val *v1, const struct ldb_val *v2)
@@ -1427,6 +1471,7 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .ldif_read_fn     = ldb_handler_copy,
                .ldif_write_fn    = ldb_handler_copy,
                .canonicalise_fn  = ldif_canonicalise_int32,
+               .index_format_fn  = ldif_index_format_int32,
                .comparison_fn    = ldif_comparison_int32,
                .operator_fn      = samba_syntax_operator_fn
        },{
index 4b94d392cc666022764f7e69fcc432a8da99aa6a..cecddb371cbf1b63e209819e04c269c3e1b3edf9 100644 (file)
@@ -146,6 +146,52 @@ static int ldb_canonicalise_Integer(struct ldb_context *ldb, void *mem_ctx,
        return 0;
 }
 
+/*
+ * Lexicographically ordered format for a ldap Integer
+ */
+static int ldb_index_format_Integer(struct ldb_context *ldb,
+                                   void *mem_ctx,
+                                   const struct ldb_val *in,
+                                   struct ldb_val *out)
+{
+       int64_t i;
+       int ret;
+       char prefix;
+       size_t len;
+
+       ret = val_to_int64(in, &i);
+       if (ret != LDB_SUCCESS) {
+               return ret;
+       }
+
+       if (i < 0) {
+               prefix = 'n';
+               i = INT64_MAX + i + 1;
+       } else if (i > 0) {
+               prefix = 'p';
+       } else {
+               prefix = 'o';
+       }
+
+       out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%c%019lld", prefix, (long long)i);
+       if (out->data == NULL) {
+               ldb_oom(ldb);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       len = talloc_array_length(out->data) - 1;
+       if (len != 20) {
+               ldb_debug(ldb, LDB_DEBUG_ERROR,
+                         __location__ ": expected index format str %s to"
+                         " have length 20 but got %zu",
+                         (char*)out->data, len);
+               return LDB_ERR_OPERATIONS_ERROR;
+       }
+
+       out->length = 20;
+       return 0;
+}
+
 /*
   compare two Integers
 */
@@ -428,7 +474,15 @@ static const struct ldb_schema_syntax ldb_standard_syntaxes[] = {
                .canonicalise_fn = ldb_canonicalise_Integer,
                .comparison_fn   = ldb_comparison_Integer
        },
-       { 
+       {
+               .name            = LDB_SYNTAX_ORDERED_INTEGER,
+               .ldif_read_fn    = ldb_handler_copy,
+               .ldif_write_fn   = ldb_handler_copy,
+               .canonicalise_fn = ldb_canonicalise_Integer,
+               .index_format_fn = ldb_index_format_Integer,
+               .comparison_fn   = ldb_comparison_Integer
+       },
+       {
                .name            = LDB_SYNTAX_OCTET_STRING,
                .ldif_read_fn    = ldb_handler_copy,
                .ldif_write_fn   = ldb_handler_copy,
index 267b7af5a88880b5b44c94d771cc7d49df5bbad0..7ee6a44dd5eef16a3ab04cb3cf5ad2c42542e192 100644 (file)
@@ -477,6 +477,12 @@ const struct ldb_dn_extended_syntax *ldb_dn_extended_syntax_by_name(struct ldb_c
 */
 #define LDB_SYNTAX_INTEGER              "1.3.6.1.4.1.1466.115.121.1.27"
 
+/**
+  Custom attribute syntax for an integer whose index is lexicographically
+  ordered by attribute value in the database.
+*/
+#define LDB_SYNTAX_ORDERED_INTEGER      "LDB_SYNTAX_ORDERED_INTEGER"
+
 /**
   LDAP attribute syntax for a boolean
 
index 10a4b6cb55d5ed184254faa2905f9f48c4a5389d..6e845d15c36cf56a3e9eeecc2b4decda1e529483 100644 (file)
@@ -4410,6 +4410,7 @@ static PyObject* module_init(void)
        ADD_LDB_STRING(SYNTAX_DN);
        ADD_LDB_STRING(SYNTAX_DIRECTORY_STRING);
        ADD_LDB_STRING(SYNTAX_INTEGER);
+       ADD_LDB_STRING(SYNTAX_ORDERED_INTEGER);
        ADD_LDB_STRING(SYNTAX_BOOLEAN);
        ADD_LDB_STRING(SYNTAX_OCTET_STRING);
        ADD_LDB_STRING(SYNTAX_UTC_TIME);
index f9f63330e97c4285c7b2e2dae775a73999bff601..b61f170f0831add151537bf2381ccbcbd98d6e77 100644 (file)
@@ -33,7 +33,7 @@
 /* change this when we change something in our schema code that
  * requires a re-index of the database
  */
-#define SAMDB_INDEXING_VERSION "2"
+#define SAMDB_INDEXING_VERSION "3"
 
 /*
   override the name to attribute handler function
index a100f35505258311498abc71f0b9250407ab5947..a67ecde222ea27c874ee2da2ab7b561d8d6df30c 100644 (file)
@@ -2541,7 +2541,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .validate_ldb           = dsdb_syntax_INT64_validate_ldb,
                .equality               = "integerMatch",
                .comment                = "Large Integer",
-               .ldb_syntax             = LDB_SYNTAX_INTEGER,
+               .ldb_syntax             = LDB_SYNTAX_ORDERED_INTEGER,
                .auto_normalise         = true
        },{
                .name                   = "String(NT-Sec-Desc)",