+ /* Allocate a string to hold the partial DN of each component */
+ if ((pPartialDN = talloc_strdup(ldb, "")) == NULL) {
+ return -1;
+ }
+
+ /* For each component of the DN (starting with the last one)... */
+ eid = 0;
+ for (nComponent = pExplodedDN->comp_num - 1, bFirst = TRUE;
+ nComponent >= 0;
+ nComponent--, bFirst = FALSE) {
+
+ /* Point to the component */
+ pComponent = pExplodedDN->components[nComponent];
+
+ /* Add this component on to the partial DN to date */
+ if ((p = talloc_asprintf(ldb,
+ "%s%s%s",
+ pComponent->component,
+ bFirst ? "" : ",",
+ pPartialDN)) == NULL) {
+ return -1;
+ }
+
+ /* No need for the old partial DN any more */
+ talloc_free(pPartialDN);
+
+ /* Save the new partial DN */
+ pPartialDN = p;
+
+ /*
+ * Ensure that an entry is in the ldb_entry table for this
+ * component. Any component other than the last one
+ * (component 0) may already exist. It is an error if
+ * component 0 (the full DN requested to be be inserted)
+ * already exists.
+ */
+ if (bFirst) {
+ /* This is a top-level entry. Parent EID is null. */
+ QUERY_NOROWS(lsqlite3,
+ FALSE,
+ "INSERT %s INTO ldb_entry "
+ " (peid, dn) "
+ " VALUES "
+ " (NULL, %q);",
+ nComponent == 0 ? "" : "OR IGNORE",
+ pPartialDN);
+ } else {
+ QUERY_NOROWS(lsqlite3,
+ FALSE,
+ "INSERT %s INTO ldb_entry "
+ " (peid, dn) "
+ " VALUES "
+ " (%lld, %q);",
+ nComponent == 0 ? "" : "OR IGNORE",
+ eid, pPartialDN);
+ }
+
+ /* Get the EID of the just inserted row (the next parent) */
+ eid = sqlite3_last_insert_rowid(lsqlite3->sqlite);
+ }
+
+ /* Give 'em what they came for! */
+ *pEID = eid;
+
+ return 0;