summaryrefslogtreecommitdiffstats
path: root/src/db/sysdb.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2016-05-23 18:18:00 +0200
committerJakub Hrozek <jhrozek@redhat.com>2016-06-23 13:47:07 +0200
commita257259b05d62ebe548b6c798a3aa03a97dbc0c2 (patch)
treeaf4cc3c4e1e109bcf25b673ce06beb85a2a4536d /src/db/sysdb.c
parentdd285415d7a8d8376207960cfa3e977524c3b98c (diff)
downloadsssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.tar.gz
sssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.tar.xz
sssd-a257259b05d62ebe548b6c798a3aa03a97dbc0c2.zip
SYSDB: If modifyTimestamp is the same, only update the TS cache
Resolves: https://fedorahosted.org/sssd/ticket/2602 If the entry being saved contains the original modifyTimestamp attribute and the modifyTimestamp attribute is the same as the one we already saved to the timestamp cache, only the expire timestamps in the asynchronous timestamp cache will be bumped and the sysdb code will avoid writes to the main cache completely. If the modifyTimestamp is either missing or differs, we assume the entry had changed and do a full write to the main cache. Also amends the generic sysdb_set_attrs* and similar functions that their results is also reflected in the timestamps cache. Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src/db/sysdb.c')
-rw-r--r--src/db/sysdb.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index 81b731a0d..1224e96ad 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1524,6 +1524,42 @@ errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count,
return EOK;
}
+struct ldb_message *sysdb_attrs2msg(TALLOC_CTX *mem_ctx,
+ struct ldb_dn *entry_dn,
+ struct sysdb_attrs *attrs,
+ int mod_op)
+{
+ struct ldb_message *msg;
+ errno_t ret;
+
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ msg->dn = entry_dn;
+
+ msg->elements = talloc_array(msg, struct ldb_message_element, attrs->num);
+ if (msg->elements == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ for (int i = 0; i < attrs->num; i++) {
+ msg->elements[i] = attrs->a[i];
+ msg->elements[i].flags = mod_op;
+ }
+ msg->num_elements = attrs->num;
+
+ ret = EOK;
+done:
+ if (ret != EOK) {
+ talloc_zfree(msg);
+ }
+ return msg;
+}
+
int sysdb_compare_usn(const char *a, const char *b)
{
size_t len_a;
@@ -1715,3 +1751,43 @@ bool is_ts_ldb_dn(struct ldb_dn *dn)
return false;
}
+
+bool sysdb_msg_attrs_modts_differs(struct ldb_message *old_entry,
+ struct sysdb_attrs *new_entry)
+{
+ const char *old_entry_ts_attr = NULL;
+ const char *new_entry_ts_attr = NULL;
+ errno_t ret;
+
+ old_entry_ts_attr = ldb_msg_find_attr_as_string(old_entry,
+ SYSDB_ORIG_MODSTAMP,
+ NULL);
+ if (old_entry_ts_attr == NULL) {
+ /* we didn't know the originalModifyTimestamp earlier. Regardless
+ * of whether the new_entry has the timestamp, we should do
+ * a comparison of the attributes
+ */
+ return true;
+ }
+
+ if (new_entry == NULL) {
+ return false;
+ }
+
+ ret = sysdb_attrs_get_string(new_entry, SYSDB_ORIG_MODSTAMP,
+ &new_entry_ts_attr);
+ if (ret != EOK) {
+ /* Nothing to compare against in the new entry either, do
+ * a comparison of the attributes
+ */
+ return true;
+ }
+
+ if (old_entry_ts_attr != NULL
+ && new_entry_ts_attr != NULL
+ && strcmp(old_entry_ts_attr, new_entry_ts_attr) == 0) {
+ return false;
+ }
+
+ return true;
+}