ldb-samba: Added handler to decode dnsProperty attribute
[rusty/samba.git] / lib / ldb-samba / ldif_handlers.c
index bb5232a8f59a6fad1dcf86c69ffece053e0ce860..9c49f755ac4b324aa1be3cad587daecfd2b9b339 100644 (file)
@@ -449,8 +449,13 @@ static int ldif_write_sddlSecurityDescriptor(struct ldb_context *ldb, void *mem_
 }
 
 /* 
-   canonicalise an objectCategory.  We use the short form as the canonical form:
-   cn=Person,cn=Schema,cn=Configuration,<basedn> becomes 'person'
+   canonicalise an objectCategory.  We use the long form as the canonical form:
+   'person' becomes cn=Person,cn=Schema,cn=Configuration,<basedn>
+
+   Also any short name of an objectClass that points to a different
+   class (such as user) has the canonical form of the class it's
+   defaultObjectCategory points to (eg
+   cn=Person,cn=Schema,cn=Configuration,<basedn>)
 */
 
 static int ldif_canonicalise_objectCategory(struct ldb_context *ldb, void *mem_ctx,
@@ -909,6 +914,19 @@ static int ldif_write_dnsRecord(struct ldb_context *ldb, void *mem_ctx,
                              true);
 }
 
+/*
+  convert a NDR formatted blob to a ldif formatted dnsProperty
+*/
+static int ldif_write_dnsProperty(struct ldb_context *ldb, void *mem_ctx,
+                               const struct ldb_val *in, struct ldb_val *out)
+{
+       return ldif_write_NDR(ldb, mem_ctx, in, out,
+                             sizeof(struct dnsp_DnsProperty),
+                             (ndr_pull_flags_fn_t)ndr_pull_dnsp_DnsProperty,
+                             (ndr_print_fn_t)ndr_print_dnsp_DnsProperty,
+                             true);
+}
+
 /*
   convert a NDR formatted blob of a supplementalCredentials into text
 */
@@ -922,6 +940,32 @@ static int ldif_write_supplementalCredentialsBlob(struct ldb_context *ldb, void
                              true);
 }
 
+/*
+  convert a NDR formatted blob to a ldif formatted trustAuthInOutBlob
+*/
+static int ldif_write_trustAuthInOutBlob(struct ldb_context *ldb, void *mem_ctx,
+                                          const struct ldb_val *in, struct ldb_val *out)
+{
+       return ldif_write_NDR(ldb, mem_ctx, in, out,
+                             sizeof(struct trustAuthInOutBlob),
+                             (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob,
+                             (ndr_print_fn_t)ndr_print_trustAuthInOutBlob,
+                             true);
+}
+
+/*
+  convert a NDR formatted blob of a partialAttributeSet into text
+*/
+static int ldif_write_partialAttributeSet(struct ldb_context *ldb, void *mem_ctx,
+                                         const struct ldb_val *in, struct ldb_val *out)
+{
+       return ldif_write_NDR(ldb, mem_ctx, in, out,
+                             sizeof(struct partialAttributeSetBlob),
+                             (ndr_pull_flags_fn_t)ndr_pull_partialAttributeSetBlob,
+                             (ndr_print_fn_t)ndr_print_partialAttributeSetBlob,
+                             true);
+}
+
 
 static int extended_dn_write_hex(struct ldb_context *ldb, void *mem_ctx,
                                 const struct ldb_val *in, struct ldb_val *out)
@@ -1113,6 +1157,65 @@ static int samba_syntax_operator_fn(struct ldb_context *ldb, enum ldb_parse_op o
        return LDB_ERR_INAPPROPRIATE_MATCHING;
 }
 
+/*
+  see if two DNs match, comparing first by GUID, then by SID, and
+  finally by string components
+ */
+static int samba_dn_extended_match(struct ldb_context *ldb,
+                                  const struct ldb_val *v1,
+                                  const struct ldb_val *v2,
+                                  bool *matched)
+{
+       TALLOC_CTX *tmp_ctx;
+       struct ldb_dn *dn1, *dn2;
+       const struct ldb_val *guid1, *guid2, *sid1, *sid2;
+       uint32_t rmd_flags1, rmd_flags2;
+
+       tmp_ctx = talloc_new(ldb);
+
+       dn1 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v1);
+       dn2 = ldb_dn_from_ldb_val(tmp_ctx, ldb, v2);
+       if (!dn1 || !dn2) {
+               /* couldn't parse as DN's */
+               talloc_free(tmp_ctx);
+               (*matched) = false;
+               return LDB_SUCCESS;
+       }
+
+       rmd_flags1 = dsdb_dn_rmd_flags(dn1);
+       rmd_flags2 = dsdb_dn_rmd_flags(dn2);
+
+       if ((rmd_flags1 & DSDB_RMD_FLAG_DELETED) !=
+           (rmd_flags2 & DSDB_RMD_FLAG_DELETED)) {
+               /* only match if they have the same deletion status */
+               talloc_free(tmp_ctx);
+               (*matched) = false;
+               return LDB_SUCCESS;
+       }
+
+
+       guid1 = ldb_dn_get_extended_component(dn1, "GUID");
+       guid2 = ldb_dn_get_extended_component(dn2, "GUID");
+       if (guid1 && guid2) {
+               (*matched) = (data_blob_cmp(guid1, guid2) == 0);
+               talloc_free(tmp_ctx);
+               return LDB_SUCCESS;
+       }
+
+       sid1 = ldb_dn_get_extended_component(dn1, "SID");
+       sid2 = ldb_dn_get_extended_component(dn2, "SID");
+       if (sid1 && sid2) {
+               (*matched) = (data_blob_cmp(sid1, sid2) == 0);
+               talloc_free(tmp_ctx);
+               return LDB_SUCCESS;
+       }
+
+       (*matched) = (ldb_dn_compare(dn1, dn2) == 0);
+
+       talloc_free(tmp_ctx);
+       return LDB_SUCCESS;
+}
+
 /*
   special operation for DNs, to take account of the RMD_FLAGS deleted bit
  */
@@ -1122,9 +1225,17 @@ static int samba_syntax_operator_dn(struct ldb_context *ldb, enum ldb_parse_op o
 {
        if (operation == LDB_OP_PRESENT && dsdb_dn_is_deleted_val(v1)) {
                /* If the DN is deleted, then we can't search for it */
+
+               /* should this be for equality too? */
                *matched = false;
                return LDB_SUCCESS;
        }
+
+       if (operation == LDB_OP_EQUALITY &&
+           samba_dn_extended_match(ldb, v1, v2, matched) == LDB_SUCCESS) {
+               return LDB_SUCCESS;
+       }
+
        return samba_syntax_operator_fn(ldb, operation, a, v1, v2, matched);
 }
 
@@ -1207,6 +1318,13 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .canonicalise_fn  = ldb_handler_copy,
                .comparison_fn    = ldb_comparison_binary,
                .operator_fn      = samba_syntax_operator_fn
+       },{
+               .name             = LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB,
+               .ldif_read_fn     = ldb_handler_copy,
+               .ldif_write_fn    = ldif_write_trustAuthInOutBlob,
+               .canonicalise_fn  = ldb_handler_copy,
+               .comparison_fn    = ldb_comparison_binary,
+               .operator_fn      = samba_syntax_operator_fn
        },{
                .name             = DSDB_SYNTAX_BINARY_DN,
                .ldif_read_fn     = ldb_handler_copy,
@@ -1242,6 +1360,13 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .canonicalise_fn  = ldb_handler_copy,
                .comparison_fn    = ldb_comparison_binary,
                .operator_fn      = samba_syntax_operator_fn
+       },{
+               .name             = LDB_SYNTAX_SAMBA_DNSPROPERTY,
+               .ldif_read_fn     = ldb_handler_copy,
+               .ldif_write_fn    = ldif_write_dnsProperty,
+               .canonicalise_fn  = ldb_handler_copy,
+               .comparison_fn    = ldb_comparison_binary,
+               .operator_fn      = samba_syntax_operator_fn
        },{
                .name             = LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS,
                .ldif_read_fn     = ldb_handler_copy,
@@ -1249,6 +1374,13 @@ static const struct ldb_schema_syntax samba_syntaxes[] = {
                .canonicalise_fn  = ldb_handler_copy,
                .comparison_fn    = ldb_comparison_binary,
                .operator_fn      = samba_syntax_operator_fn
+       },{
+               .name             = LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET,
+               .ldif_read_fn     = ldb_handler_copy,
+               .ldif_write_fn    = ldif_write_partialAttributeSet,
+               .canonicalise_fn  = ldb_handler_copy,
+               .comparison_fn    = ldb_comparison_binary,
+               .operator_fn      = samba_syntax_operator_fn
        }
 };
 
@@ -1323,6 +1455,8 @@ static const struct {
        { "repsTo",                     LDB_SYNTAX_SAMBA_REPSFROMTO },
        { "replPropertyMetaData",       LDB_SYNTAX_SAMBA_REPLPROPERTYMETADATA },
        { "replUpToDateVector",         LDB_SYNTAX_SAMBA_REPLUPTODATEVECTOR },
+       { "trustAuthIncoming",          LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB },
+       { "trustAuthOutgoing",          LDB_SYNTAX_SAMBA_TRUSTAUTHINOUTBLOB },
        { "rIDAllocationPool",          LDB_SYNTAX_SAMBA_RANGE64 },
        { "rIDPreviousAllocationPool",  LDB_SYNTAX_SAMBA_RANGE64 },
        { "rIDAvailablePool",           LDB_SYNTAX_SAMBA_RANGE64 },
@@ -1366,7 +1500,9 @@ static const struct {
 
        /* These NDR encoded things we want to be able to read with --show-binary */
        { "dnsRecord",                          LDB_SYNTAX_SAMBA_DNSRECORD },
-       { "supplementalCredentials",            LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS}
+       { "dnsProperty",                        LDB_SYNTAX_SAMBA_DNSPROPERTY },
+       { "supplementalCredentials",            LDB_SYNTAX_SAMBA_SUPPLEMENTALCREDENTIALS},
+       { "partialAttributeSet",                LDB_SYNTAX_SAMBA_PARTIALATTRIBUTESET}
 };
 
 const struct ldb_schema_syntax *ldb_samba_syntax_by_name(struct ldb_context *ldb, const char *name)