s4:dsdb Break up 'parse a DN from DRSUAPI' into a subfunction
[ira/wip.git] / source4 / dsdb / schema / schema_syntax.c
index f656728a54d5898b4f519d4fc6da5fc35288e7a2..edf5df8aa9b14ff971bad616ffe53f1010513d8d 100644 (file)
@@ -684,9 +684,9 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               uint32_t v;
+               uint32_t attid;
                WERROR status;
-               const char *str;
+               const char *oid;
 
                if (in->value_ctr.values[i].blob == NULL) {
                        return WERR_FOOBAR;
@@ -696,12 +696,12 @@ static WERROR _dsdb_syntax_OID_oid_drsuapi_to_ldb(struct ldb_context *ldb,
                        return WERR_FOOBAR;
                }
 
-               v = IVAL(in->value_ctr.values[i].blob->data, 0);
+               attid = IVAL(in->value_ctr.values[i].blob->data, 0);
 
-               status = dsdb_map_int2oid(schema, v, out->values, &str);
+               status = dsdb_schema_pfm_oid_from_attid(schema->prefixmap, attid, out->values, &oid);
                W_ERROR_NOT_OK_RETURN(status);
 
-               out->values[i] = data_blob_string_const(str);
+               out->values[i] = data_blob_string_const(oid);
        }
 
        return WERR_OK;
@@ -1028,6 +1028,89 @@ static WERROR dsdb_syntax_UNICODE_ldb_to_drsuapi(struct ldb_context *ldb,
        return WERR_OK;
 }
 
+
+WERROR dsdb_syntax_one_DN_drsuapi_to_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, 
+                                        const struct dsdb_syntax *syntax, 
+                                        struct smb_iconv_convenience *iconv_convenience,
+                                        const DATA_BLOB *in, DATA_BLOB *out)
+{
+       struct drsuapi_DsReplicaObjectIdentifier3 id3;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB guid_blob;
+       struct ldb_dn *dn;
+       TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+       int ret;
+
+       if (!tmp_ctx) {
+               W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
+       }
+       
+       if (in == NULL) {
+               talloc_free(tmp_ctx);
+               return WERR_FOOBAR;
+       }
+       
+       if (in->length == 0) {
+               talloc_free(tmp_ctx);
+               return WERR_FOOBAR;
+       }
+       
+       
+       /* windows sometimes sends an extra two pad bytes here */
+       ndr_err = ndr_pull_struct_blob(in,
+                                      tmp_ctx, 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);
+               talloc_free(tmp_ctx);
+               return ntstatus_to_werror(status);
+       }
+       
+       dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
+       if (!dn) {
+               talloc_free(tmp_ctx);
+               /* If this fails, it must be out of memory, as it does not do much parsing */
+               W_ERROR_HAVE_NO_MEMORY(dn);
+       }
+       
+       ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, iconv_convenience, &id3.guid,
+                                      (ndr_push_flags_fn_t)ndr_push_GUID);
+       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+               talloc_free(tmp_ctx);
+               return ntstatus_to_werror(status);
+       }
+       
+       ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
+       if (ret != LDB_SUCCESS) {
+               talloc_free(tmp_ctx);
+               return WERR_FOOBAR;
+       }
+       
+       talloc_free(guid_blob.data);
+       
+       if (id3.__ndr_size_sid) {
+               DATA_BLOB sid_blob;
+               ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, iconv_convenience, &id3.sid,
+                                              (ndr_push_flags_fn_t)ndr_push_dom_sid);
+               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(status);
+               }
+               
+               ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
+               if (ret != LDB_SUCCESS) {
+                       talloc_free(tmp_ctx);
+                       return WERR_FOOBAR;
+               }
+       }
+       
+       *out = data_blob_string_const(ldb_dn_get_extended_linearized(mem_ctx, dn, 1));
+       talloc_free(tmp_ctx);
+       return WERR_OK;
+}
+
 static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb, 
                                            const struct dsdb_schema *schema,
                                            const struct dsdb_attribute *attr,
@@ -1036,7 +1119,6 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
                                            struct ldb_message_element *out)
 {
        uint32_t i;
-       int ret;
 
        out->flags      = 0;
        out->name       = talloc_strdup(mem_ctx, attr->lDAPDisplayName);
@@ -1047,78 +1129,14 @@ static WERROR dsdb_syntax_DN_drsuapi_to_ldb(struct ldb_context *ldb,
        W_ERROR_HAVE_NO_MEMORY(out->values);
 
        for (i=0; i < out->num_values; i++) {
-               struct drsuapi_DsReplicaObjectIdentifier3 id3;
-               enum ndr_err_code ndr_err;
-               DATA_BLOB guid_blob;
-               struct ldb_dn *dn;
-               TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-               if (!tmp_ctx) {
-                       W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
-               }
-
-               if (in->value_ctr.values[i].blob == NULL) {
-                       talloc_free(tmp_ctx);
-                       return WERR_FOOBAR;
-               }
-
-               if (in->value_ctr.values[i].blob->length == 0) {
-                       talloc_free(tmp_ctx);
-                       return WERR_FOOBAR;
-               }
-
-               
-               /* windows sometimes sends an extra two pad bytes here */
-               ndr_err = ndr_pull_struct_blob(in->value_ctr.values[i].blob,
-                                              tmp_ctx, 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);
-                       talloc_free(tmp_ctx);
-                       return ntstatus_to_werror(status);
-               }
-
-               dn = ldb_dn_new(tmp_ctx, ldb, id3.dn);
-               if (!dn) {
-                       talloc_free(tmp_ctx);
-                       /* If this fails, it must be out of memory, as it does not do much parsing */
-                       W_ERROR_HAVE_NO_MEMORY(dn);
-               }
-
-               ndr_err = ndr_push_struct_blob(&guid_blob, tmp_ctx, schema->iconv_convenience, &id3.guid,
-                                              (ndr_push_flags_fn_t)ndr_push_GUID);
-               if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
-                       talloc_free(tmp_ctx);
-                       return ntstatus_to_werror(status);
-               }
-
-               ret = ldb_dn_set_extended_component(dn, "GUID", &guid_blob);
-               if (ret != LDB_SUCCESS) {
-                       talloc_free(tmp_ctx);
-                       return WERR_FOOBAR;
-               }
-
-               talloc_free(guid_blob.data);
-
-               if (id3.__ndr_size_sid) {
-                       DATA_BLOB sid_blob;
-                       ndr_err = ndr_push_struct_blob(&sid_blob, tmp_ctx, schema->iconv_convenience, &id3.sid,
-                                                      (ndr_push_flags_fn_t)ndr_push_dom_sid);
-                       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                               NTSTATUS status = ndr_map_error2ntstatus(ndr_err);
-                               talloc_free(tmp_ctx);
-                               return ntstatus_to_werror(status);
-                       }
-
-                       ret = ldb_dn_set_extended_component(dn, "SID", &sid_blob);
-                       if (ret != LDB_SUCCESS) {
-                               talloc_free(tmp_ctx);
-                               return WERR_FOOBAR;
-                       }
-               }
-
-               out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
-               talloc_free(tmp_ctx);
+               WERROR status = dsdb_syntax_one_DN_drsuapi_to_ldb(out->values, ldb, attr->syntax, 
+                                                                 schema->iconv_convenience, 
+                                                                 in->value_ctr.values[i].blob, 
+                                                                 &out->values[i]);
+               if (!W_ERROR_IS_OK(status)) {
+                       return status;
+               }
+                                                 
        }
 
        return WERR_OK;
@@ -1229,6 +1247,7 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
                enum ndr_err_code ndr_err;
                DATA_BLOB guid_blob;
                struct ldb_dn *dn;
+               struct dsdb_dn *dsdb_dn;
                TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
                if (!tmp_ctx) {
                        W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
@@ -1296,9 +1315,13 @@ static WERROR dsdb_syntax_DN_BINARY_drsuapi_to_ldb(struct ldb_context *ldb,
                }
 
                /* set binary stuff */
-               ldb_dn_set_binary(dn, &id3.binary);
-
-               out->values[i] = data_blob_string_const(ldb_dn_get_extended_linearized(out->values, dn, 1));
+               dsdb_dn = dsdb_dn_construct(tmp_ctx, dn, id3.binary, attr->syntax->ldap_oid);
+               if (!dsdb_dn) {
+                       /* If this fails, it must be out of memory, we know the ldap_oid is valid */
+                       talloc_free(tmp_ctx);
+                       W_ERROR_HAVE_NO_MEMORY(dsdb_dn);
+               }
+               out->values[i] = data_blob_string_const(dsdb_dn_get_extended_linearized(out->values, dsdb_dn, 1));
                talloc_free(tmp_ctx);
        }
 
@@ -1333,17 +1356,20 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
                struct drsuapi_DsReplicaObjectIdentifier3Binary id3;
                enum ndr_err_code ndr_err;
                const DATA_BLOB *guid_blob, *sid_blob;
-               struct ldb_dn *dn;
+               struct dsdb_dn *dsdb_dn;
                TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
                W_ERROR_HAVE_NO_MEMORY(tmp_ctx);
 
                out->value_ctr.values[i].blob   = &blobs[i];
 
-               dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &in->values[i]);
+               dsdb_dn = dsdb_dn_parse(tmp_ctx, ldb, &in->values[i], attr->syntax->ldap_oid);
 
-               W_ERROR_HAVE_NO_MEMORY(dn);
+               if (!dsdb_dn) {
+                       talloc_free(tmp_ctx);
+                       return ntstatus_to_werror(NT_STATUS_INVALID_PARAMETER);
+               }
 
-               guid_blob = ldb_dn_get_extended_component(dn, "GUID");
+               guid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "GUID");
 
                ZERO_STRUCT(id3);
 
@@ -1358,7 +1384,7 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
                        }
                }
 
-               sid_blob = ldb_dn_get_extended_component(dn, "SID");
+               sid_blob = ldb_dn_get_extended_component(dsdb_dn->dn, "SID");
                if (sid_blob) {
                        
                        ndr_err = ndr_pull_struct_blob_all(sid_blob, 
@@ -1371,16 +1397,10 @@ static WERROR dsdb_syntax_DN_BINARY_ldb_to_drsuapi(struct ldb_context *ldb,
                        }
                }
 
-               id3.dn = ldb_dn_get_linearized(dn);
-               if (strncmp(id3.dn, "B:", 2) == 0) {
-                       id3.dn = strchr(id3.dn, ':');
-                       id3.dn = strchr(id3.dn+1, ':');
-                       id3.dn = strchr(id3.dn+1, ':');
-                       id3.dn++;
-               }
+               id3.dn = ldb_dn_get_linearized(dsdb_dn->dn);
 
                /* get binary stuff */
-               ldb_dn_get_binary(dn, &id3.binary);
+               id3.binary = dsdb_dn->extra_part;
 
                ndr_err = ndr_push_struct_blob(&blobs[i], blobs, schema->iconv_convenience, &id3, (ndr_push_flags_fn_t)ndr_push_drsuapi_DsReplicaObjectIdentifier3Binary);
                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
@@ -1661,7 +1681,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .comment                = "Object(DS-DN) == a DN",
        },{
                .name                   = "Object(DN-Binary)",
-               .ldap_oid               = "1.2.840.113556.1.4.903",
+               .ldap_oid               = DSDB_SYNTAX_BINARY_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0b"),
                .attributeSyntax_oid    = "2.5.5.7",
@@ -1669,7 +1689,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .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)",
@@ -1716,7 +1735,7 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
        },{
        /* not used in w2k3 schema */
                .name                   = "Object(DN-String)",
-               .ldap_oid               = "1.2.840.113556.1.4.904",
+               .ldap_oid               = DSDB_SYNTAX_STRING_DN,
                .oMSyntax               = 127,
                .oMObjectClass          = OMOBJECTCLASS("\x2a\x86\x48\x86\xf7\x14\x01\x01\x01\x0c"),
                .attributeSyntax_oid    = "2.5.5.14",
@@ -1724,7 +1743,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
                .ldb_to_drsuapi         = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
                .equality               = "octetStringMatch",
                .comment                = "OctetString: String+DN",
-               .ldb_syntax             = LDB_SYNTAX_OCTET_STRING,
        }
 };