summaryrefslogtreecommitdiffstats
path: root/src/back-sch.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@redhat.com>2012-03-15 19:50:45 -0400
committerNalin Dahyabhai <nalin@redhat.com>2012-03-15 19:50:45 -0400
commit6d78b63916f725300472b28c3c7b283afc72ac2e (patch)
tree3a6b31ef245d77d9549b698e012cd5866b8d894a /src/back-sch.c
parent533ee3d75dd65eb6b4a6df0c718ddd16fadac33a (diff)
downloadslapi-nis-6d78b63916f725300472b28c3c7b283afc72ac2e.tar.gz
slapi-nis-6d78b63916f725300472b28c3c7b283afc72ac2e.tar.xz
slapi-nis-6d78b63916f725300472b28c3c7b283afc72ac2e.zip
- 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)
Diffstat (limited to 'src/back-sch.c')
-rw-r--r--src/back-sch.c84
1 files changed, 79 insertions, 5 deletions
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);
}