Correct handling of 32-bit integer attributes in SAMBA 4
authorMatthias Dieter Wallnöfer <mwallnoefer@yahoo.de>
Thu, 18 Jun 2009 09:05:45 +0000 (11:05 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 19 Jun 2009 01:32:01 +0000 (11:32 +1000)
- LDB handles now all 32-bit integer attributes correctly (also with overflows)
  according to the schema
- LDAP backends handle the attributes "groupType", "userAccountControl" and
  "sAMAccountType" correctly. This handling doesn't yet use the schema but
  the conversion file "simple_ldap.map.c" which contains them hardcoded.
  Did also a refactoring of the conversion function there.
- Bug #6136 should be gone

.gitignore
source4/dsdb/samdb/ldb_modules/simple_ldap_map.c
source4/dsdb/schema/schema_syntax.c
source4/lib/ldb-samba/ldif_handlers.c
source4/lib/ldb-samba/ldif_handlers.h

index e8e1dfa327d820723024b91faa2cab5cfd1fd421..1ace6e73a4a8c77047a591d80655d9b068b20fc9 100644 (file)
@@ -206,7 +206,6 @@ source4/lib/ldb/examples/ldbreader
 source4/lib/ldb/examples/ldifreader
 source4/lib/ldb/lib
 source4/lib/ldb/man/*.html
-source4/lib/ldb-samba/ldif_handlers.h
 source4/lib/ldb/samba/ldif_handlers_proto.h
 source4/lib/ldb/tests/tmp
 source4/libnet/libnet_proto.h
index 948241b0944154d595e9db3403b862fdde74dda2..0a6c350a3b0e636f14a7f16e43c2de2c8db0d179 100644 (file)
@@ -146,19 +146,10 @@ static struct ldb_val objectCategory_always_dn(struct ldb_module *module, TALLOC
 
 static struct ldb_val normalise_to_signed32(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
 {
-       long long int signed_ll = strtoll((const char *)val->data, NULL, 10);
-       if (signed_ll >= 0x80000000LL) {
-               union {
-                       int32_t signed_int;
-                       uint32_t unsigned_int;
-               } u = {
-                       .unsigned_int = strtoul((const char *)val->data, NULL, 10)
-               };
-
-               struct ldb_val out = data_blob_string_const(talloc_asprintf(ctx, "%d", u.signed_int));
-               return out;
-       }
-       return val_copy(module, ctx, val);
+       struct ldb_val out;
+       int32_t i = (int32_t) strtol((char *)val->data, NULL, 0);
+       out = data_blob_string_const(talloc_asprintf(ctx, "%d", i));
+       return out;
 }
 
 static struct ldb_val usn_to_entryCSN(struct ldb_module *module, TALLOC_CTX *ctx, const struct ldb_val *val)
@@ -358,6 +349,17 @@ static const struct ldb_map_attribute entryuuid_attributes[] =
                         },
                }
        },
+       {
+               .local_name = "userAccountControl",
+               .type = MAP_CONVERT,
+               .u = {
+                       .convert = {
+                                .remote_name = "userAccountControl",
+                                .convert_local = normalise_to_signed32,
+                                .convert_remote = val_copy,
+                        },
+               }
+       },
        {
                .local_name = "sAMAccountType",
                .type = MAP_CONVERT,
@@ -499,6 +501,17 @@ static const struct ldb_map_attribute nsuniqueid_attributes[] =
                         },
                }
        },
+       {
+               .local_name = "userAccountControl",
+               .type = MAP_CONVERT,
+               .u = {
+                       .convert = {
+                                .remote_name = "userAccountControl",
+                                .convert_local = normalise_to_signed32,
+                                .convert_remote = val_copy,
+                        },
+               }
+       },
        {
                .local_name = "sAMAccountType",
                .type = MAP_CONVERT,
index 4fd6501cc8bc238461bbfab844f32660f931aec4..4ff861766fda3d0d22fb5be8ffe048691bd9a4ab 100644 (file)
@@ -1243,6 +1243,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
                .equality               = "integerMatch",
                .comment                = "Integer",
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
        },{
                .name                   = "String(Octet)",
                .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
@@ -1279,6 +1280,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.9",
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_INT32
        },{
        /* not used in w2k3 forest */
                .name                   = "String(Numeric)",
index 30be444048a1e010dad0149a2593a6a558253ba2..43cb960310e97a65c87556e58b335352f3c97d06 100644 (file)
@@ -3,6 +3,7 @@
 
    Copyright (C) Andrew Tridgell 2005
    Copyright (C) Andrew Bartlett 2006-2007
+   Copyright (C) Matthias Dieter Wallnöfer 2009
      ** NOTE! The following LGPL license applies to the ldb
      ** library. This does NOT imply that all of Samba is released
      ** under the LGPL
@@ -79,7 +80,7 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx,
        return 0;
 }
 
-static bool ldb_comparision_objectSid_isString(const struct ldb_val *v)
+static bool ldif_comparision_objectSid_isString(const struct ldb_val *v)
 {
        if (v->length < 3) {
                return false;
@@ -93,13 +94,13 @@ static bool ldb_comparision_objectSid_isString(const struct ldb_val *v)
 /*
   compare two objectSids
 */
-static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
+static int ldif_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
                                    const struct ldb_val *v1, const struct ldb_val *v2)
 {
-       if (ldb_comparision_objectSid_isString(v1) && ldb_comparision_objectSid_isString(v2)) {
+       if (ldif_comparision_objectSid_isString(v1) && ldif_comparision_objectSid_isString(v2)) {
                return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
-       } else if (ldb_comparision_objectSid_isString(v1)
-                  && !ldb_comparision_objectSid_isString(v2)) {
+       } else if (ldif_comparision_objectSid_isString(v1)
+                  && !ldif_comparision_objectSid_isString(v2)) {
                struct ldb_val v;
                int ret;
                if (ldif_read_objectSid(ldb, mem_ctx, v1, &v) != 0) {
@@ -109,8 +110,8 @@ static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
                ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
                talloc_free(v.data);
                return ret;
-       } else if (!ldb_comparision_objectSid_isString(v1)
-                  && ldb_comparision_objectSid_isString(v2)) {
+       } else if (!ldif_comparision_objectSid_isString(v1)
+                  && ldif_comparision_objectSid_isString(v2)) {
                struct ldb_val v;
                int ret;
                if (ldif_read_objectSid(ldb, mem_ctx, v2, &v) != 0) {
@@ -127,10 +128,10 @@ static int ldb_comparison_objectSid(struct ldb_context *ldb, void *mem_ctx,
 /*
   canonicalise a objectSid
 */
-static int ldb_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx,
+static int ldif_canonicalise_objectSid(struct ldb_context *ldb, void *mem_ctx,
                                      const struct ldb_val *in, struct ldb_val *out)
 {
-       if (ldb_comparision_objectSid_isString(in)) {
+       if (ldif_comparision_objectSid_isString(in)) {
                if (ldif_read_objectSid(ldb, mem_ctx, in, out) != 0) {
                        /* Perhaps not a string after all */
                        return ldb_handler_copy(ldb, mem_ctx, in, out);
@@ -145,7 +146,7 @@ static int extended_dn_read_SID(struct ldb_context *ldb, void *mem_ctx,
 {
        struct dom_sid sid;
        enum ndr_err_code ndr_err;
-       if (ldb_comparision_objectSid_isString(in)) {
+       if (ldif_comparision_objectSid_isString(in)) {
                if (ldif_read_objectSid(ldb, mem_ctx, in, out) == 0) {
                        return 0;
                }
@@ -214,7 +215,7 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx,
        return 0;
 }
 
-static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v)
+static bool ldif_comparision_objectGUID_isString(const struct ldb_val *v)
 {
        if (v->length != 36 && v->length != 38) return false;
 
@@ -257,13 +258,13 @@ static int extended_dn_read_GUID(struct ldb_context *ldb, void *mem_ctx,
 /*
   compare two objectGUIDs
 */
-static int ldb_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx,
+static int ldif_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx,
                                     const struct ldb_val *v1, const struct ldb_val *v2)
 {
-       if (ldb_comparision_objectGUID_isString(v1) && ldb_comparision_objectGUID_isString(v2)) {
+       if (ldif_comparision_objectGUID_isString(v1) && ldif_comparision_objectGUID_isString(v2)) {
                return ldb_comparison_binary(ldb, mem_ctx, v1, v2);
-       } else if (ldb_comparision_objectGUID_isString(v1)
-                  && !ldb_comparision_objectGUID_isString(v2)) {
+       } else if (ldif_comparision_objectGUID_isString(v1)
+                  && !ldif_comparision_objectGUID_isString(v2)) {
                struct ldb_val v;
                int ret;
                if (ldif_read_objectGUID(ldb, mem_ctx, v1, &v) != 0) {
@@ -273,8 +274,8 @@ static int ldb_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx,
                ret = ldb_comparison_binary(ldb, mem_ctx, &v, v2);
                talloc_free(v.data);
                return ret;
-       } else if (!ldb_comparision_objectGUID_isString(v1)
-                  && ldb_comparision_objectGUID_isString(v2)) {
+       } else if (!ldif_comparision_objectGUID_isString(v1)
+                  && ldif_comparision_objectGUID_isString(v2)) {
                struct ldb_val v;
                int ret;
                if (ldif_read_objectGUID(ldb, mem_ctx, v2, &v) != 0) {
@@ -291,10 +292,10 @@ static int ldb_comparison_objectGUID(struct ldb_context *ldb, void *mem_ctx,
 /*
   canonicalise a objectGUID
 */
-static int ldb_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx,
+static int ldif_canonicalise_objectGUID(struct ldb_context *ldb, void *mem_ctx,
                                       const struct ldb_val *in, struct ldb_val *out)
 {
-       if (ldb_comparision_objectGUID_isString(in)) {
+       if (ldif_comparision_objectGUID_isString(in)) {
                if (ldif_read_objectGUID(ldb, mem_ctx, in, out) != 0) {
                        /* Perhaps it wasn't a valid string after all */
                        return ldb_handler_copy(ldb, mem_ctx, in, out);
@@ -626,6 +627,31 @@ static int ldif_comparison_prefixMap(struct ldb_context *ldb, void *mem_ctx,
        return ret;
 }
 
+/* Canonicalisation of two 32-bit integers */
+static int ldif_canonicalise_int32(struct ldb_context *ldb, void *mem_ctx,
+                       const struct ldb_val *in, struct ldb_val *out)
+{
+       char *end;
+       int32_t i = (int32_t) strtol((char *)in->data, &end, 0);
+       if (*end != 0) {
+               return -1;
+       }
+       out->data = (uint8_t *) talloc_asprintf(mem_ctx, "%d", i);
+       if (out->data == NULL) {
+               return -1;
+       }
+       out->length = strlen((char *)out->data);
+       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)
+{
+       return (int32_t) strtol((char *)v1->data, NULL, 0)
+        - (int32_t) strtol((char *)v2->data, NULL, 0);
+}
+
 static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx,
                                 const struct ldb_val *in, struct ldb_val *out)
 {
@@ -636,18 +662,13 @@ static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx,
        return 0;
 }
 
-
-#define LDB_SYNTAX_SAMBA_GUID                  "LDB_SYNTAX_SAMBA_GUID"
-#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY       "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY"
-#define LDB_SYNTAX_SAMBA_PREFIX_MAP    "LDB_SYNTAX_SAMBA_PREFIX_MAP"
-
 static const struct ldb_schema_syntax samba_syntaxes[] = {
        {
                .name             = LDB_SYNTAX_SAMBA_SID,
                .ldif_read_fn     = ldif_read_objectSid,
                .ldif_write_fn    = ldif_write_objectSid,
-               .canonicalise_fn  = ldb_canonicalise_objectSid,
-               .comparison_fn    = ldb_comparison_objectSid
+               .canonicalise_fn  = ldif_canonicalise_objectSid,
+               .comparison_fn    = ldif_comparison_objectSid
        },{
                .name             = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
                .ldif_read_fn     = ldif_read_ntSecurityDescriptor,
@@ -658,8 +679,8 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .name             = LDB_SYNTAX_SAMBA_GUID,
                .ldif_read_fn     = ldif_read_objectGUID,
                .ldif_write_fn    = ldif_write_objectGUID,
-               .canonicalise_fn  = ldb_canonicalise_objectGUID,
-               .comparison_fn    = ldb_comparison_objectGUID
+               .canonicalise_fn  = ldif_canonicalise_objectGUID,
+               .comparison_fn    = ldif_comparison_objectGUID
        },{
                .name             = LDB_SYNTAX_SAMBA_OBJECT_CATEGORY,
                .ldif_read_fn     = ldb_handler_copy,
@@ -672,6 +693,12 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .ldif_write_fn    = ldif_write_prefixMap,
                .canonicalise_fn  = ldif_canonicalise_prefixMap,
                .comparison_fn    = ldif_comparison_prefixMap
+       },{
+               .name             = LDB_SYNTAX_SAMBA_INT32,
+               .ldif_read_fn     = ldb_handler_copy,
+               .ldif_write_fn    = ldb_handler_copy,
+               .canonicalise_fn  = ldif_canonicalise_int32,
+               .comparison_fn    = ldif_comparison_int32
        }
 };
 
@@ -694,6 +721,7 @@ static const struct ldb_dn_extended_syntax samba_dn_syntax[] = {
        }
 };
 
+/* TODO: Should be dynamic at some point */
 static const struct {
        const char *name;
        const char *syntax;
index e37c4166c82ac93a1a2a60eec7b1c21e612c3987..3e1f17e057be3cb72748c9d25f89282244f1a3a6 100644 (file)
@@ -3,6 +3,10 @@
 
 #define LDB_SYNTAX_SAMBA_SID                   "LDB_SYNTAX_SAMBA_SID"
 #define LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR   "1.2.840.113556.1.4.907"
+#define LDB_SYNTAX_SAMBA_GUID                  "LDB_SYNTAX_SAMBA_GUID"
+#define LDB_SYNTAX_SAMBA_OBJECT_CATEGORY       "LDB_SYNTAX_SAMBA_OBJECT_CATEGORY"
+#define LDB_SYNTAX_SAMBA_PREFIX_MAP            "LDB_SYNTAX_SAMBA_PREFIX_MAP"
+#define LDB_SYNTAX_SAMBA_INT32                 "LDB_SYNTAX_SAMBA_INT32"
 
 #include "lib/ldb-samba/ldif_handlers_proto.h"