/* use ndr_print_* to convert a NDR formatted blob to a ldif formatted blob If mask_errors is true, then function succeeds but out data is set to "<Unable to decode binary data>" message \return 0 on success; -1 on error */ static int ldif_write_NDR(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out, size_t struct_size, ndr_pull_flags_fn_t pull_fn, ndr_print_fn_t print_fn, bool mask_errors) { uint8_t *p; enum ndr_err_code err; if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) { return ldb_handler_copy(ldb, mem_ctx, in, out); } p = talloc_size(mem_ctx, struct_size); err = ndr_pull_struct_blob(in, mem_ctx, p, pull_fn); if (err != NDR_ERR_SUCCESS) { /* fail in not in mask_error mode */ if (!mask_errors) { return -1; } talloc_free(p); out->data = (uint8_t *)talloc_strdup(mem_ctx, "<Unable to decode binary data>"); out->length = strlen((const char *)out->data); return 0; } out->data = (uint8_t *)ndr_print_struct_string(mem_ctx, print_fn, "NDR", p); talloc_free(p); if (out->data == NULL) { return ldb_handler_copy(ldb, mem_ctx, in, out); } out->length = strlen((char *)out->data); return 0; }
/* convert a NDR formatted blob to a ldif formatted ntSecurityDescriptor (SDDL format) */ static int ldif_write_ntSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct security_descriptor *sd; enum ndr_err_code ndr_err; if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { return ldif_write_NDR(ldb, mem_ctx, in, out, sizeof(struct security_descriptor), (ndr_pull_flags_fn_t)ndr_pull_security_descriptor, (ndr_print_fn_t)ndr_print_security_descriptor, true); } sd = talloc(mem_ctx, struct security_descriptor); if (sd == NULL) { return -1; } /* We can't use ndr_pull_struct_blob_all because this contains relative pointers */ ndr_err = ndr_pull_struct_blob(in, sd, sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(sd); return -1; } out->data = (uint8_t *)sddl_encode(mem_ctx, sd, samdb_domain_sid_cache_only(ldb)); talloc_free(sd); if (out->data == NULL) { return -1; } out->length = strlen((const char *)out->data); return 0; }
static int ldif_write_dn_binary_NDR(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out, size_t struct_size, ndr_pull_flags_fn_t pull_fn, ndr_print_fn_t print_fn, bool mask_errors) { uint8_t *p = NULL; enum ndr_err_code err; struct dsdb_dn *dsdb_dn = NULL; char *dn_str = NULL; char *str = NULL; if (!(ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY)) { return ldb_handler_copy(ldb, mem_ctx, in, out); } dsdb_dn = dsdb_dn_parse(mem_ctx, ldb, in, DSDB_SYNTAX_BINARY_DN); if (dsdb_dn == NULL) { return ldb_handler_copy(ldb, mem_ctx, in, out); } p = talloc_size(dsdb_dn, struct_size); if (p == NULL) { TALLOC_FREE(dsdb_dn); return ldb_handler_copy(ldb, mem_ctx, in, out); } err = ndr_pull_struct_blob(&dsdb_dn->extra_part, p, p, pull_fn); if (err != NDR_ERR_SUCCESS) { /* fail in not in mask_error mode */ if (!mask_errors) { return -1; } TALLOC_FREE(dsdb_dn); return ldb_handler_copy(ldb, mem_ctx, in, out); } dn_str = ldb_dn_get_extended_linearized(dsdb_dn, dsdb_dn->dn, 1); if (dn_str == NULL) { TALLOC_FREE(dsdb_dn); return ldb_handler_copy(ldb, mem_ctx, in, out); } str = ndr_print_struct_string(mem_ctx, print_fn, dn_str, p); TALLOC_FREE(dsdb_dn); if (str == NULL) { return ldb_handler_copy(ldb, mem_ctx, in, out); } *out = data_blob_string_const(str); return 0; }
/* convert a string formatted SDDL to a ldif formatted ntSecurityDescriptor (SDDL format) */ static int ldif_write_sddlSecurityDescriptor(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { struct security_descriptor *sd; const struct dom_sid *sid = samdb_domain_sid(ldb); sd = sddl_decode(mem_ctx, (const char *)in->data, sid); out->data = (uint8_t *)ndr_print_struct_string(mem_ctx, (ndr_print_fn_t)ndr_print_security_descriptor, "SDDL", sd); out->length = strlen((const char *)out->data); talloc_free(sd); return 0; } return ldb_handler_copy(ldb, mem_ctx, in, out); }
/* convert a NDR formatted blob to a ldif formatted prefixMap */ static int ldif_write_prefixMap(struct ldb_context *ldb, void *mem_ctx, const struct ldb_val *in, struct ldb_val *out) { struct prefixMapBlob *blob; enum ndr_err_code ndr_err; char *string; uint32_t i; if (ldb_get_flags(ldb) & LDB_FLG_SHOW_BINARY) { int err; /* try to decode the blob as S4 prefixMap */ err = ldif_write_NDR(ldb, mem_ctx, in, out, sizeof(struct prefixMapBlob), (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob, (ndr_print_fn_t)ndr_print_prefixMapBlob, false); if (0 == err) { return err; } /* try parsing it as Windows PrefixMap value */ return ldif_write_NDR(ldb, mem_ctx, in, out, sizeof(struct drsuapi_MSPrefixMap_Ctr), (ndr_pull_flags_fn_t)ndr_pull_drsuapi_MSPrefixMap_Ctr, (ndr_print_fn_t)ndr_print_drsuapi_MSPrefixMap_Ctr, true); } blob = talloc(mem_ctx, struct prefixMapBlob); if (blob == NULL) { return -1; } ndr_err = ndr_pull_struct_blob_all(in, blob, blob, (ndr_pull_flags_fn_t)ndr_pull_prefixMapBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { goto failed; } if (blob->version != PREFIX_MAP_VERSION_DSDB) { goto failed; } string = talloc_strdup(mem_ctx, ""); if (string == NULL) { goto failed; } for (i=0; i < blob->ctr.dsdb.num_mappings; i++) { DATA_BLOB oid_blob; char *partial_oid = NULL; if (i > 0) { string = talloc_asprintf_append(string, ";"); } oid_blob = data_blob_const(blob->ctr.dsdb.mappings[i].oid.binary_oid, blob->ctr.dsdb.mappings[i].oid.length); if (!ber_read_partial_OID_String(blob, oid_blob, &partial_oid)) { DEBUG(0, ("ber_read_partial_OID failed on prefixMap item with id: 0x%X", blob->ctr.dsdb.mappings[i].id_prefix)); goto failed; } string = talloc_asprintf_append(string, "%u:%s", blob->ctr.dsdb.mappings[i].id_prefix, partial_oid); talloc_free(discard_const(partial_oid)); if (string == NULL) { goto failed; } } talloc_free(blob); *out = data_blob_string_const(string); return 0; failed: talloc_free(blob); return -1; }