Don't treat the DN+binary syntax as a DN.
[kai/samba.git] / source4 / dsdb / schema / schema_syntax.c
index 444d0a3b8d96fa6f9af95338e5c911f225aa3e03..7aed08605bef9aa5c299a20b88d7410199e0bc8f 100644 (file)
@@ -2,11 +2,13 @@
    Unix SMB/CIFS mplementation.
    DSDB schema syntaxes
    
-   Copyright (C) Stefan Metzmacher 2006
-    
+   Copyright (C) Stefan Metzmacher <metze@samba.org> 2006
+   Copyright (C) Simo Sorce 2005
+   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008
+
    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,
@@ -15,8 +17,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/>.
    
 */
 #include "includes.h"
@@ -24,7 +25,7 @@
 #include "librpc/gen_ndr/ndr_drsuapi.h"
 #include "lib/ldb/include/ldb.h"
 #include "system/time.h"
-#include "lib/charset/charset.h"
+#include "../lib/util/charset/charset.h"
 #include "librpc/ndr/libndr.h"
 
 static WERROR dsdb_syntax_FOOBAR_drsuapi_to_ldb(const struct dsdb_schema *schema,
@@ -262,7 +263,7 @@ static WERROR dsdb_syntax_INT64_drsuapi_to_ldb(const struct dsdb_schema *schema,
 
                v = BVALS(in->value_ctr.values[i].blob->data, 0);
 
-               str = talloc_asprintf(out->values, "%lld", v);
+               str = talloc_asprintf(out->values, "%lld", (long long int)v);
                W_ERROR_HAVE_NO_MEMORY(str);
 
                out->values[i] = data_blob_string_const(str);
@@ -767,7 +768,9 @@ static WERROR dsdb_syntax_UNICODE_drsuapi_to_ldb(const struct dsdb_schema *schem
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
+               ret = convert_string_talloc_convenience(out->values, 
+                                               schema->iconv_convenience, 
+                                                                       CH_UTF16, CH_UNIX,
                                            in->value_ctr.values[i].blob->data,
                                            in->value_ctr.values[i].blob->length,
                                            (void **)&str);
@@ -809,7 +812,7 @@ static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(const struct dsdb_schema *schem
 
                out->value_ctr.values[i].blob   = &blobs[i];
 
-               ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
+               ret = convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
                                            in->values[i].data,
                                            in->values[i].length,
                                            (void **)&blobs[i].data);
@@ -840,7 +843,7 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
 
        for (i=0; i < out->num_values; i++) {
                struct drsuapi_DsReplicaObjectIdentifier3 id3;
-               NTSTATUS status;
+               enum ndr_err_code ndr_err;
 
                if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
@@ -850,10 +853,11 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(const struct dsdb_schema *schema,
                        return WERR_FOOBAR;
                }
 
-               status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
-                                                 out->values, &id3,
-                                                 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
-               if (!NT_STATUS_IS_OK(status)) {
+               ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
+                                                  out->values, schema->iconv_convenience, &id3,
+                                                  (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
                        return ntstatus_to_werror(status);
                }
 
@@ -888,8 +892,8 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               NTSTATUS status;
                struct drsuapi_DsReplicaObjectIdentifier3 id3;
+               enum ndr_err_code ndr_err;
 
                out->value_ctr.values[i].blob   = &blobs[i];
 
@@ -897,9 +901,9 @@ static WERROR dsdb_syntax_DN_ldb_to_drsuapi(const struct dsdb_schema *schema,
                ZERO_STRUCT(id3);
                id3.dn = (const char *)in->values[i].data;
 
-               status = ndr_push_struct_blob(&blobs[i], blobs, &id3,
-                                             (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
-               if (!NT_STATUS_IS_OK(status)) {
+               ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
                        return ntstatus_to_werror(status);
                }
        }
@@ -927,7 +931,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *sch
                struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
                char *binary;
                char *str;
-               NTSTATUS status;
+               enum ndr_err_code ndr_err;
 
                if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
@@ -937,10 +941,11 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *sch
                        return WERR_FOOBAR;
                }
 
-               status = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
-                                                 out->values, &id3b,
-                                                 (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
-               if (!NT_STATUS_IS_OK(status)) {
+               ndr_err = ndr_pull_struct_blob_all(in->value_ctr.values[i].blob,
+                                                  out->values, schema->iconv_convenience, &id3b,
+                                                  (ndr_pull_flags_fn_t)ndr_pull_drsuapi_DsReplicaObjectIdentifier3Binary);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
                        return ntstatus_to_werror(status);
                }
 
@@ -949,7 +954,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(const struct dsdb_schema *sch
                W_ERROR_HAVE_NO_MEMORY(binary);
 
                str = talloc_asprintf(out->values, "B:%u:%s:%s",
-                                     id3b.binary.length * 2, /* because of 2 hex chars per byte */
+                                     (unsigned int)(id3b.binary.length * 2), /* because of 2 hex chars per byte */
                                      binary,
                                      id3b.dn);
                W_ERROR_HAVE_NO_MEMORY(str);
@@ -985,8 +990,8 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *sch
        W_ERROR_HAVE_NO_MEMORY(blobs);
 
        for (i=0; i < in->num_values; i++) {
-               NTSTATUS status;
                struct drsuapi_DsReplicaObjectIdentifier3Binary id3b;
+               enum ndr_err_code ndr_err;
 
                out->value_ctr.values[i].blob   = &blobs[i];
 
@@ -995,9 +1000,10 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(const struct dsdb_schema *sch
                id3b.dn         = (const char *)in->values[i].data;
                id3b.binary     = data_blob(NULL, 0);
 
-               status = ndr_push_struct_blob(&blobs[i], blobs, &id3b,
-                                             (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
-               if (!NT_STATUS_IS_OK(status)) {
+               ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3b,
+                                              (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
                        return ntstatus_to_werror(status);
                }
        }
@@ -1040,7 +1046,7 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb(const struct dsdb_
                        return WERR_FOOBAR;
                }
 
-               ret = convert_string_talloc(out->values, CH_UTF16, CH_UNIX,
+               ret = convert_string_talloc_convenience(out->values, schema->iconv_convenience, CH_UTF16, CH_UNIX,
                                            in->value_ctr.values[i].blob->data+4,
                                            in->value_ctr.values[i].blob->length-4,
                                            (void **)&str);
@@ -1083,7 +1089,7 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_
 
                out->value_ctr.values[i].blob   = &blobs[i];
 
-               ret = convert_string_talloc(blobs, CH_UNIX, CH_UTF16,
+               ret = convert_string_talloc_convenience(blobs, schema->iconv_convenience, CH_UNIX, CH_UTF16,
                                            in->values[i].data,
                                            in->values[i].length,
                                            (void **)&data);
@@ -1105,7 +1111,6 @@ static WERROR dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi(const struct dsdb_
        return WERR_OK;
 }
 
-
 #define OMOBJECTCLASS(val) { .length = sizeof(val) - 1, .data = discard_const_p(uint8_t, val) }
 
 static const struct dsdb_syntax dsdb_syntaxes[] = {
@@ -1116,27 +1121,36 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.8",
                .drsuapi_to_ldb         = dsdb_syntax_BOOL_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_BOOL_ldb_to_drsuapi,
+               .equality               = "booleanMatch",
+               .comment                = "Boolean" 
        },{
                .name                   = "Integer",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
+               .ldap_oid               = LDB_SYNTAX_INTEGER,
                .oMSyntax               = 2,
                .attributeSyntax_oid    = "2.5.5.9",
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT32_ldb_to_drsuapi,
+               .equality               = "integerMatch",
+               .comment                = "Integer",
        },{
                .name                   = "String(Octet)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
+               .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
                .oMSyntax               = 4,
                .attributeSyntax_oid    = "2.5.5.10",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "octetStringMatch",
+               .comment                = "Octet String",
        },{
                .name                   = "String(Sid)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.40",
+               .ldap_oid               = LDB_SYNTAX_OCTET_STRING,
                .oMSyntax               = 4,
                .attributeSyntax_oid    = "2.5.5.17",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "octetStringMatch",
+               .comment                = "Octet String - Security Identifier (SID)",
+               .ldb_syntax             = LDB_SYNTAX_SAMBA_SID
        },{
                .name                   = "String(Object-Identifier)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.38",
@@ -1144,9 +1158,12 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.2",
                .drsuapi_to_ldb         = dsdb_syntax_OID_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_OID_ldb_to_drsuapi,
+               .equality               = "caseIgnoreMatch", /* Would use "objectIdentifierMatch" but most are ldap attribute/class names */
+               .comment                = "OID String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING
        },{
                .name                   = "Enumeration",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.27",
+               .ldap_oid               = LDB_SYNTAX_INTEGER,
                .oMSyntax               = 10,
                .attributeSyntax_oid    = "2.5.5.9",
                .drsuapi_to_ldb         = dsdb_syntax_INT32_drsuapi_to_ldb,
@@ -1159,6 +1176,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.6",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "numericStringMatch",
+               .substring              = "numericStringSubstringsMatch",
+               .comment                = "Numeric String" 
        },{
                .name                   = "String(Printable)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.44",
@@ -1173,6 +1193,10 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.4",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Case Insensitive String",
+               .ldb_syntax             = LDB_SYNTAX_DIRECTORY_STRING,
        },{
                .name                   = "String(IA5)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.26",
@@ -1180,6 +1204,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.5",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
+               .equality               = "caseExactIA5Match",
+               .comment                = "Printable String"
        },{
                .name                   = "String(UTC-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.53",
@@ -1187,6 +1213,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.11",
                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_UTC_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_UTC_ldb_to_drsuapi,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "UTC Time",
        },{
                .name                   = "String(Generalized-Time)",
                .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.24",
@@ -1194,6 +1222,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.11",
                .drsuapi_to_ldb         = dsdb_syntax_NTTIME_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_NTTIME_ldb_to_drsuapi,
+               .equality               = "generalizedTimeMatch",
+               .comment                = "Generalized Time",
+               .ldb_syntax             = LDB_SYNTAX_UTC_TIME,
        },{
        /* not used in w2k3 schema */
                .name                   = "String(Case Sensitive)",
@@ -1204,11 +1235,14 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
        },{
                .name                   = "String(Unicode)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.15",
+               .ldap_oid               = LDB_SYNTAX_DIRECTORY_STRING,
                .oMSyntax               = 64,
                .attributeSyntax_oid    = "2.5.5.12",
                .drsuapi_to_ldb         = dsdb_syntax_UNICODE_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_UNICODE_ldb_to_drsuapi,
+               .equality               = "caseIgnoreMatch",
+               .substring              = "caseIgnoreSubstringsMatch",
+               .comment                = "Directory String",
        },{
                .name                   = "Interval/LargeInteger",
                .ldap_oid               = "1.2.840.113556.1.4.906",
@@ -1216,21 +1250,26 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.16",
                .drsuapi_to_ldb         = dsdb_syntax_INT64_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_INT64_ldb_to_drsuapi,
+               .equality               = "integerMatch",
+               .comment                = "Large Integer",
+               .ldb_syntax             = LDB_SYNTAX_INTEGER,
        },{
                .name                   = "String(NT-Sec-Desc)",
-               .ldap_oid               = "1.2.840.113556.1.4.907",
+               .ldap_oid               = LDB_SYNTAX_SAMBA_SECURITY_DESCRIPTOR,
                .oMSyntax               = 66,
                .attributeSyntax_oid    = "2.5.5.15",
                .drsuapi_to_ldb         = dsdb_syntax_DATA_BLOB_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DATA_BLOB_ldb_to_drsuapi,
        },{
                .name                   = "Object(DS-DN)",
-               .ldap_oid               = "1.3.6.1.4.1.1466.115.121.1.12",
+               .ldap_oid               = LDB_SYNTAX_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2b\x0c\x02\x87\x73\x1c\x00\x85\x4a"),
                .attributeSyntax_oid    = "2.5.5.1",
                .drsuapi_to_ldb         = dsdb_syntax_DN_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DN_ldb_to_drsuapi,
+               .equality               = "distinguishedNameMatch",
+               .comment                = "Object(DS-DN) == a DN",
        },{
                .name                   = "Object(DN-Binary)",
                .ldap_oid               = "1.2.840.113556.1.4.903",
@@ -1239,6 +1278,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.7",
                .drsuapi_to_ldb         = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
+               .equality               = "octetStringMatch",
+               .comment                = "OctetString: Binary+DN",
+               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(OR-Name)",
@@ -1270,6 +1312,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.13",
                .drsuapi_to_ldb         = dsdb_syntax_PRESENTATION_ADDRESS_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_PRESENTATION_ADDRESS_ldb_to_drsuapi,
+               .comment                = "Presentation Address" 
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(Access-Point)",
@@ -1288,9 +1331,44 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .attributeSyntax_oid    = "2.5.5.14",
                .drsuapi_to_ldb         = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
                .ldb_to_drsuapi         = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+               .equality               = "distinguishedNameMatch",
+               .comment                = "OctetString: String+DN",
+               .ldb_syntax             = LDB_SYNTAX_DN,
        }
 };
 
+const struct dsdb_syntax *find_syntax_map_by_ad_oid(const char *ad_oid) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (strcasecmp(ad_oid, dsdb_syntaxes[i].attributeSyntax_oid) == 0) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
+
+const struct dsdb_syntax *find_syntax_map_by_ad_syntax(int oMSyntax) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (oMSyntax == dsdb_syntaxes[i].oMSyntax) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
+
+const struct dsdb_syntax *find_syntax_map_by_standard_oid(const char *standard_oid) 
+{
+       int i;
+       for (i=0; dsdb_syntaxes[i].ldap_oid; i++) {
+               if (strcasecmp(standard_oid, dsdb_syntaxes[i].ldap_oid) == 0) {
+                       return &dsdb_syntaxes[i];
+               }
+       }
+       return NULL;
+}
 const struct dsdb_syntax *dsdb_syntax_for_attribute(const struct dsdb_attribute *attr)
 {
        uint32_t i;