/* create extra attribute shortcuts */ static void dsdb_setup_attribute_shortcuts(struct ldb_context *ldb, struct dsdb_schema *schema) { struct dsdb_attribute *attribute; /* setup fast access to one_way_link and DN format */ for (attribute=schema->attributes; attribute; attribute=attribute->next) { attribute->dn_format = dsdb_dn_oid_to_format(attribute->syntax->ldap_oid); if (attribute->dn_format == DSDB_INVALID_DN) { attribute->one_way_link = false; continue; } /* these are not considered to be one way links for the purpose of DN link fixups */ if (ldb_attr_cmp("distinguishedName", attribute->lDAPDisplayName) == 0 || ldb_attr_cmp("objectCategory", attribute->lDAPDisplayName) == 0) { attribute->one_way_link = false; continue; } if (attribute->linkID == 0) { attribute->one_way_link = true; continue; } /* handle attributes with a linkID but no backlink */ if ((attribute->linkID & 1) == 0 && dsdb_attribute_by_linkID(schema, attribute->linkID + 1) == NULL) { attribute->one_way_link = true; continue; } attribute->one_way_link = false; } }
struct dsdb_dn *dsdb_dn_parse(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, const struct ldb_val *dn_blob, const char *dn_oid) { struct dsdb_dn *dsdb_dn; struct ldb_dn *dn; const char *data; size_t len; TALLOC_CTX *tmp_ctx; char *p1; char *p2; uint32_t blen; struct ldb_val bval; struct ldb_val dval; char *dn_str; enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(dn_oid); switch (dn_format) { case DSDB_INVALID_DN: return NULL; case DSDB_NORMAL_DN: { dn = ldb_dn_from_ldb_val(mem_ctx, ldb, dn_blob); if (!dn || !ldb_dn_validate(dn)) { talloc_free(dn); return NULL; } return dsdb_dn_construct_internal(mem_ctx, dn, data_blob_null, dn_format, dn_oid); } case DSDB_BINARY_DN: if (dn_blob->length < 2 || dn_blob->data[0] != 'B' || dn_blob->data[1] != ':') { return NULL; } break; case DSDB_STRING_DN: if (dn_blob->length < 2 || dn_blob->data[0] != 'S' || dn_blob->data[1] != ':') { return NULL; } break; default: return NULL; } if (dn_blob && dn_blob->data && (strlen((const char*)dn_blob->data) != dn_blob->length)) { /* The RDN must not contain a character with value 0x0 */ return NULL; } if (!dn_blob->data || dn_blob->length == 0) { return NULL; } tmp_ctx = talloc_new(mem_ctx); if (tmp_ctx == NULL) { return NULL; } data = (const char *)dn_blob->data; len = dn_blob->length - 2; p1 = talloc_strndup(tmp_ctx, (const char *)dn_blob->data + 2, len); if (!p1) { goto failed; } errno = 0; blen = strtoul(p1, &p2, 10); if (errno != 0) { DEBUG(10, (__location__ ": failed\n")); goto failed; } if (p2 == NULL) { DEBUG(10, (__location__ ": failed\n")); goto failed; } if (p2[0] != ':') { DEBUG(10, (__location__ ": failed\n")); goto failed; } len -= PTR_DIFF(p2,p1);//??? p1 = p2+1; len--; if (blen >= len) { DEBUG(10, (__location__ ": blen=%u len=%u\n", (unsigned)blen, (unsigned)len)); goto failed; } p2 = p1 + blen; if (p2[0] != ':') { DEBUG(10, (__location__ ": %s", p2)); goto failed; } dn_str = p2+1; switch (dn_format) { case DSDB_BINARY_DN: if ((blen % 2 != 0)) { DEBUG(10, (__location__ ": blen=%u - not an even number\n", (unsigned)blen)); goto failed; } if (blen >= 2) { bval.length = (blen/2)+1; bval.data = talloc_size(tmp_ctx, bval.length); if (bval.data == NULL) { DEBUG(10, (__location__ ": err\n")); goto failed; } bval.data[bval.length-1] = 0; bval.length = strhex_to_str((char *)bval.data, bval.length, p1, blen); if (bval.length != (blen / 2)) { DEBUG(10, (__location__ ": non hexidecimal characters found in binary prefix\n")); goto failed; } } else { bval = data_blob_null; } break; case DSDB_STRING_DN: bval = data_blob(p1, blen); break; default: /* never reached */ return NULL; } dval.data = (uint8_t *)dn_str; dval.length = strlen(dn_str); dn = ldb_dn_from_ldb_val(tmp_ctx, ldb, &dval); if (!dn || !ldb_dn_validate(dn)) { DEBUG(10, (__location__ ": err\n")); goto failed; } dsdb_dn = dsdb_dn_construct(mem_ctx, dn, bval, dn_oid); return dsdb_dn; failed: talloc_free(tmp_ctx); return NULL; }
struct dsdb_dn *dsdb_dn_construct(TALLOC_CTX *mem_ctx, struct ldb_dn *dn, DATA_BLOB extra_part, const char *oid) { enum dsdb_dn_format dn_format = dsdb_dn_oid_to_format(oid); return dsdb_dn_construct_internal(mem_ctx, dn, extra_part, dn_format, oid); }