From 6d78b63916f725300472b28c3c7b283afc72ac2e Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 15 Mar 2012 19:50:45 -0400 Subject: - add setting of a synthetic entry's entryUSN based on the source entry's entryUSN or the root DSE's lastUSN (if we have no source entry) --- src/back-sch.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 5 deletions(-) (limited to 'src/back-sch.c') diff --git a/src/back-sch.c b/src/back-sch.c index 2e2d195..2870d4b 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -247,12 +247,80 @@ backend_entry_free_entry_data(void *p) free(data); } +/* Retrieve the USN of the passed-in entry, or the last-USN value from the root + * DSE, or NULL. The result needs to be free()d. */ +static char * +backend_entry_get_usn(Slapi_PBlock *pb, Slapi_Entry *e, + struct plugin_state *state) +{ + Slapi_Entry *root; + Slapi_ValueSet *value_set; + Slapi_Value *value; + Slapi_DN *sdn; + char *attr, *attrs[2], *actual_attr, *val; + const char *cval; + int count, disposition, buffer_flags, i; + + root = NULL; + if (e != NULL) { + /* We'll read "entryUSN" from the entry. */ + attr = SLAPI_ATTR_ENTRYUSN; + } else { + /* We'll read "lastUSN" from the root DSE. */ + attr = "lastUSN"; + attrs[0] = attr; + attrs[1] = NULL; + sdn = slapi_sdn_new_dn_byval(""); + if (sdn == NULL) { + return NULL; + } + wrap_search_internal_get_entry(pb, sdn, NULL, attrs, + &root, state->plugin_desc); + slapi_sdn_free(&sdn); + e = root; + } + /* No source entry, and failed to read the root DSE. */ + if (e == NULL) { + return NULL; + } + if (slapi_vattr_values_get(e, attr, + &value_set, + &disposition, + &actual_attr, + 0, &buffer_flags) != 0) { + /* Error reading the attribute. Bail. */ + if (root != NULL) { + slapi_entry_free(root); + } + return NULL; + } + count = slapi_valueset_count(value_set); + if (count == 1) { + if (slapi_valueset_first_value(value_set, &value) != -1) { + cval = slapi_value_get_string(value); + } else { + cval = NULL; + } + } else { + /* Either no results, or too many results. More likely no + * results, if the USN plugin isn't loaded. */ + cval = NULL; + } + val = cval ? strdup(cval) : NULL; + slapi_vattr_values_free(&value_set, &actual_attr, buffer_flags); + if (root != NULL) { + slapi_entry_free(root); + } + return val; +} + /* Add operational attributes to a synthetic entry. */ static void backend_set_operational_attributes(Slapi_Entry *e, struct plugin_state *state, time_t timestamp, - int n_subordinates) + int n_subordinates, + const char *usn) { struct tm timestamp_tm; char timestamp_str[4 + 2 + 2 + 2 + 2 + 2 + 2]; /* YYYYMMDDHHMMSSZ\0 */ @@ -273,6 +341,9 @@ backend_set_operational_attributes(Slapi_Entry *e, slapi_entry_add_string(e, "creatorsName", state->plugin_base); slapi_entry_add_string(e, "modifiersName", state->plugin_base); slapi_entry_add_string(e, "entryDN", slapi_entry_get_ndn(e)); + if ((usn != NULL) && (strlen(usn) > 0)) { + slapi_entry_add_string(e, "entryUSN", usn); + } if (n_subordinates > 0) { slapi_entry_add_string(e, "hasSubordinates", "TRUE"); snprintf(timestamp_str, sizeof(timestamp_str), "%ld", @@ -289,7 +360,7 @@ backend_set_entry(Slapi_PBlock *pb, Slapi_Entry *e, { const char *hexchars = "0123456789ABCDEF"; char *rdn, *ndn, *ldif, *plugin_id, *keys[2], *values[2], **ava, *p, *q; - char *attr, *val; + char *usn, *attr, *val; unsigned int rdn_len, value_len, *ava_lens; const char *rdnstr; int len, i, j, k, count; @@ -381,8 +452,10 @@ backend_set_entry(Slapi_PBlock *pb, Slapi_Entry *e, return; } /* Set operational attributes here so that they can be overridden. */ + usn = backend_entry_get_usn(pb, e, data->common.state); backend_set_operational_attributes(entry, data->common.state, - time(NULL), 0); + time(NULL), 0, usn); + free(usn); /* Iterate through the set of attributes. */ if (data->attribute_format != NULL) { for (i = 0; data->attribute_format[i] != NULL; i++) { @@ -899,7 +972,8 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, set_data->common.set); backend_set_operational_attributes(set_entry, cbdata->state, time(NULL), - n_entries); + n_entries, + NULL); if (!slapi_entry_rdn_values_present(set_entry)) { slapi_entry_add_rdn_values(set_entry); } @@ -970,7 +1044,7 @@ backend_search_group_cb(const char *group, void *cb_data) slapi_entry_set_sdn(group_entry, group_dn); n_maps = map_data_get_domain_size(cbdata->state, group); backend_set_operational_attributes(group_entry, cbdata->state, - time(NULL), n_maps); + time(NULL), n_maps, NULL); if (!slapi_entry_rdn_values_present(group_entry)) { slapi_entry_add_rdn_values(group_entry); } -- cgit