summaryrefslogtreecommitdiffstats
path: root/src/db/sysdb.c
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2015-12-16 14:42:04 +0100
committerJakub Hrozek <jhrozek@redhat.com>2016-01-19 14:33:04 +0100
commit68abbe716bed7c8d6790d9bec168ef44469306a1 (patch)
tree85066d550de84703072d0611627de5c7915d53c7 /src/db/sysdb.c
parente9ae5cd285dcc8fa232e16f9c7a29f18537272f2 (diff)
downloadsssd-68abbe716bed7c8d6790d9bec168ef44469306a1.tar.gz
sssd-68abbe716bed7c8d6790d9bec168ef44469306a1.tar.xz
sssd-68abbe716bed7c8d6790d9bec168ef44469306a1.zip
SUDO: make sudo sysdb interface more reusable
Reviewed-by: Sumit Bose <sbose@redhat.com>
Diffstat (limited to 'src/db/sysdb.c')
-rw-r--r--src/db/sysdb.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index a71364d7c..d4366a3c7 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -2013,3 +2013,101 @@ errno_t sysdb_msg2attrs(TALLOC_CTX *mem_ctx, size_t count,
return EOK;
}
+
+int sysdb_compare_usn(const char *a, const char *b)
+{
+ size_t len_a;
+ size_t len_b;
+
+ if (a == NULL) {
+ return -1;
+ }
+
+ if (b == NULL) {
+ return 1;
+ }
+
+ len_a = strlen(a);
+ len_b = strlen(b);
+
+ /* trim leading zeros */
+ while (len_a > 0 && *a == '0') {
+ a++;
+ len_a--;
+ }
+
+ while (len_b > 0 && *b == '0') {
+ b++;
+ len_b--;
+ }
+
+ /* less digits means lower number */
+ if (len_a < len_b) {
+ return -1;
+ }
+
+ /* more digits means bigger number */
+ if (len_a > len_b) {
+ return 1;
+ }
+
+ /* now we can compare digits since alphabetical order is the same
+ * as numeric order */
+ return strcmp(a, b);
+}
+
+errno_t sysdb_get_highest_usn(TALLOC_CTX *mem_ctx,
+ struct sysdb_attrs **attrs,
+ size_t num_attrs,
+ char **_usn)
+{
+ const char *highest = NULL;
+ const char *current = NULL;
+ char *usn;
+ errno_t ret;
+ size_t i;
+
+ if (num_attrs == 0 || attrs == NULL) {
+ goto done;
+ }
+
+ for (i = 0; i < num_attrs; i++) {
+ ret = sysdb_attrs_get_string(attrs[i], SYSDB_USN, &current);
+ if (ret == ENOENT) {
+ /* USN value is not present, assuming zero. */
+ current = "0";
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE, "Failed to retrieve USN value "
+ "[%d]: %s\n", ret, sss_strerror(ret));
+
+ return ret;
+ }
+
+ if (current == NULL) {
+ continue;
+ }
+
+ if (highest == NULL) {
+ highest = current;
+ continue;
+ }
+
+ if (sysdb_compare_usn(current, highest) > 0 ) {
+ highest = current;
+ }
+ }
+
+done:
+ if (highest == NULL) {
+ usn = talloc_strdup(mem_ctx, "0");
+ } else {
+ usn = talloc_strdup(mem_ctx, highest);
+ }
+
+ if (usn == NULL) {
+ return ENOMEM;
+ }
+
+ *_usn = usn;
+ return EOK;
+}