diff options
author | Pavel Březina <pbrezina@redhat.com> | 2015-12-16 14:42:04 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-01-19 14:33:04 +0100 |
commit | 68abbe716bed7c8d6790d9bec168ef44469306a1 (patch) | |
tree | 85066d550de84703072d0611627de5c7915d53c7 /src/db/sysdb.c | |
parent | e9ae5cd285dcc8fa232e16f9c7a29f18537272f2 (diff) | |
download | sssd-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.c | 98 |
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, ¤t); + 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; +} |