From b5e653a844af60596f9bc6b16349ee902ddb51f5 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Fri, 22 Jan 2010 09:47:52 -0800 Subject: Allow modrdn to move subtree and rename non-leaf node This patch includes - replacing the entrydn index with the entryrdn index - replacing a full DN in each entry in the DB with an RDN - extending Slapi_Entry, entry2str, and str2entry to absorb the changes made on the entry - adding DN/RDN helper functions - adding DN cache - adding a utility and a migration script to convert the DN format database to the RDN format - extending a database dump utility dbscan to support the entryrdn - slapi_dn_syntax_check by nkinder@redhat.com is added to check the dn before modify operations - big fix for 171338 - Enhancement: winsync modrdn not synced In addition to the above, compile warnings and memory leaks found in testing the new feature are fixed. For more details, see the feature design document at: http://directory.fedoraproject.org/wiki/Subtree_Rename and bugzilla at: https://bugzilla.redhat.com/show_bug.cgi?id=171338 --- ldap/servers/slapd/back-ldbm/misc.c | 112 +++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 9 deletions(-) (limited to 'ldap/servers/slapd/back-ldbm/misc.c') diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c index 8fcb81f8..137c9343 100644 --- a/ldap/servers/slapd/back-ldbm/misc.c +++ b/ldap/servers/slapd/back-ldbm/misc.c @@ -52,15 +52,16 @@ void ldbm_nasty(const char* str, int c, int err) char buffer[200]; if (err == DB_LOCK_DEADLOCK) { PR_snprintf(buffer,200,"%s WARNING %d",str,c); - LDAPDebug(LDAP_DEBUG_TRACE,"%s, err=%d %s\n", - buffer,err,(msg = dblayer_strerror( err )) ? msg : ""); + LDAPDebug(LDAP_DEBUG_TRACE,"%s, err=%d %s\n", + buffer,err,(msg = dblayer_strerror( err )) ? msg : ""); } else if (err == DB_RUNRECOVERY) { - LDAPDebug(LDAP_DEBUG_ANY,"FATAL ERROR at %s (%d); server stopping as database recovery needed.\n", str,c,0); - exit(1); + LDAPDebug2Args(LDAP_DEBUG_ANY, "FATAL ERROR at %s (%d); " + "server stopping as database recovery needed.\n", str, c); + exit(1); } else { PR_snprintf(buffer,200,"%s BAD %d",str,c); - LDAPDebug(LDAP_DEBUG_ANY,"%s, err=%d %s\n", - buffer,err,(msg = dblayer_strerror( err )) ? msg : ""); + LDAPDebug(LDAP_DEBUG_ANY, "%s, err=%d %s\n", + buffer, err, (msg = dblayer_strerror( err )) ? msg : ""); } } @@ -95,9 +96,10 @@ int return_on_disk_full(struct ldbminfo *li) static const char *systemIndexes[] = { "aci", - "entrydn", - "numsubordinates", - "parentid", + LDBM_ENTRYDN_STR, + LDBM_ENTRYRDN_STR, + LDBM_NUMSUBORDINATES_STR, + LDBM_PARENTID_STR, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_UNIQUEID, SLAPI_ATTR_NSCP_ENTRYDN, @@ -148,6 +150,21 @@ compute_entry_tombstone_dn(const char *entrydn, const char *uniqueid) return tombstone_dn; } +char * +compute_entry_tombstone_rdn(const char *entryrdn, const char *uniqueid) +{ + char *tombstone_rdn; + + PR_ASSERT(NULL != entrydn); + PR_ASSERT(NULL != uniqueid); + + tombstone_rdn = slapi_ch_smprintf("%s=%s, %s", + SLAPI_ATTR_UNIQUEID, + uniqueid, + entryrdn); + return tombstone_rdn; +} + /* mark a backend instance "busy" * returns 0 on success, -1 if the instance is ALREADY busy @@ -388,3 +405,80 @@ is_fullpath(char *path) } return 0; } + +/* + * Get value of type from string. + * Note: this function is very primitive. It does not support multi values. + * This could be used to retrieve a single value as a string from raw data + * read from db. + */ +/* caller is responsible to release "value" */ +int +get_value_from_string(const char *string, char *type, char **value) +{ + int rc = -1; + size_t typelen = 0; + char *ptr = NULL; + char *copy = NULL; + char *tmpptr = NULL; + char *tmptype = NULL; + char *valueptr = NULL; +#if defined (USE_OPENLDAP) + ber_len_t valuelen; +#else + int valuelen; +#endif + + if (NULL == string || NULL == type || NULL == value) { + return rc; + } + *value = NULL; + tmpptr = (char *)string; + ptr = PL_strcasestr(tmpptr, type); + if (NULL == ptr) { + return rc; + } + + typelen = strlen(type); + while (NULL != (ptr = ldif_getline(&tmpptr))) { + if ((0 != PL_strncasecmp(ptr, type, typelen)) || + (*(ptr + typelen) != ';' && *(ptr + typelen) != ':')) { + /* did not match */ + /* ldif_getline replaces '\n' and '\r' with '\0' */ + if ('\0' == *(tmpptr - 1)) { + *(tmpptr - 1) = '\n'; + } + if ('\0' == *(tmpptr - 2)) { + *(tmpptr - 2) = '\r'; + } + continue; + } + /* matched */ + copy = slapi_ch_strdup(ptr); + /* ldif_getline replaces '\n' and '\r' with '\0' */ + if ('\0' == *(tmpptr - 1)) { + *(tmpptr - 1) = '\n'; + } + if ('\0' == *(tmpptr - 2)) { + *(tmpptr - 2) = '\r'; + } + rc = ldif_parse_line(copy, &tmptype, &valueptr, &valuelen); + if (0 > rc || NULL == valueptr || 0 >= valuelen) { + slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "parse " + "failed: %d\n", rc); + goto bail; + } + if (0 != strcasecmp(type, tmptype)) { + slapi_log_error(SLAPI_LOG_FATAL, "get_value_from_string", "type " + "does not match: %s != %s\n", + type, tmptype); + goto bail; + } + *value = (char *)slapi_ch_malloc(valuelen + 1); + memcpy(*value, valueptr, valuelen); + *(*value + valuelen) = '\0'; + } +bail: + slapi_ch_free_string(©); + return rc; +} -- cgit