summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-12-12 14:11:11 +0100
committerJakub Hrozek <jhrozek@redhat.com>2012-12-13 20:59:57 +0100
commit5a2cce34cf8843613b0b9dfde054b3d471dd5f3a (patch)
tree746475cae3aa3fdafa178ab2d625a7ed63e1e0be
parenta9eff330a7fbd231e8cc28a6828a1e5014ddb0d2 (diff)
downloadsssd-5a2cce34cf8843613b0b9dfde054b3d471dd5f3a.tar.gz
sssd-5a2cce34cf8843613b0b9dfde054b3d471dd5f3a.tar.bz2
sssd-5a2cce34cf8843613b0b9dfde054b3d471dd5f3a.zip
sudo: support generalized time format
https://fedorahosted.org/sssd/ticket/1712 The timestamp doesn't have to be in the form yyyymmddHHMMSSZ any more. It can be in any form of generalized time format.
-rw-r--r--src/db/sysdb_sudo.c45
-rw-r--r--src/db/sysdb_sudo.h2
2 files changed, 34 insertions, 13 deletions
diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index c1845f9b..519a3aa7 100644
--- a/src/db/sysdb_sudo.c
+++ b/src/db/sysdb_sudo.c
@@ -36,6 +36,36 @@
/* ==================== Utility functions ==================== */
+static errno_t sysdb_sudo_convert_time(const char *str, time_t *time)
+{
+ struct tm tm;
+ char *tret = NULL;
+
+ /* SUDO requires times to be in generalized time format:
+ * YYYYMMDDHHMMSS[.|,fraction][(+|-HHMM)|Z]
+ *
+ * We need to use more format strings to parse this with strptime().
+ */
+ const char **format = NULL;
+ const char *formats[] = {"%Y%m%d%H%M%SZ", /* 201212121300Z */
+ "%Y%m%d%H%M%S%z", /* 201212121300+-0200 */
+ "%Y%m%d%H%M%S.0Z",
+ "%Y%m%d%H%M%S.0%z",
+ "%Y%m%d%H%M%S,0Z",
+ "%Y%m%d%H%M%S,0%z",
+ NULL};
+
+ for (format = formats; *format != NULL; format++) {
+ tret = strptime(str, *format, &tm);
+ if (tret != NULL && *tret == '\0') {
+ *time = mktime(&tm);
+ return EOK;
+ }
+ }
+
+ return EINVAL;
+}
+
static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
time_t now,
bool *result)
@@ -43,11 +73,9 @@ static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
TALLOC_CTX *tmp_ctx = NULL;
const char **values = NULL;
const char *name = NULL;
- char *tret = NULL;
time_t notBefore = 0;
time_t notAfter = 0;
time_t converted;
- struct tm tm;
errno_t ret;
int i;
@@ -67,7 +95,6 @@ static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
/*
* From man sudoers.ldap:
*
- * A timestamp is in the form yyyymmddHHMMSSZ.
* If multiple sudoNotBefore entries are present, the *earliest* is used.
* If multiple sudoNotAfter entries are present, the *last one* is used.
*
@@ -91,14 +118,12 @@ static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
}
for (i=0; values[i] ; i++) {
- tret = strptime(values[i], SYSDB_SUDO_TIME_FORMAT, &tm);
- if (tret == NULL || *tret != '\0') {
+ ret = sysdb_sudo_convert_time(values[i], &converted);
+ if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Invalid time format in rule [%s]!\n",
name));
- ret = EINVAL;
goto done;
}
- converted = mktime(&tm);
/* Grab the earliest */
if (!notBefore) {
@@ -123,14 +148,12 @@ static errno_t sysdb_sudo_check_time(struct sysdb_attrs *rule,
}
for (i=0; values[i] ; i++) {
- tret = strptime(values[i], SYSDB_SUDO_TIME_FORMAT, &tm);
- if (tret == NULL || *tret != '\0') {
+ ret = sysdb_sudo_convert_time(values[i], &converted);
+ if (ret != EOK) {
DEBUG(SSSDBG_MINOR_FAILURE, ("Invalid time format in rule [%s]!\n",
name));
- ret = EINVAL;
goto done;
}
- converted = mktime(&tm);
/* Grab the latest */
if (!notAfter) {
diff --git a/src/db/sysdb_sudo.h b/src/db/sysdb_sudo.h
index 35b350c6..f37afff8 100644
--- a/src/db/sysdb_sudo.h
+++ b/src/db/sysdb_sudo.h
@@ -45,8 +45,6 @@
#define SYSDB_SUDO_CACHE_AT_NOTAFTER "sudoNotAfter"
#define SYSDB_SUDO_CACHE_AT_ORDER "sudoOrder"
-#define SYSDB_SUDO_TIME_FORMAT "%Y%m%d%H%M%SZ"
-
/* When constructing a sysdb filter, OR these values to include.. */
#define SYSDB_SUDO_FILTER_NONE 0x00 /* no additional filter */
#define SYSDB_SUDO_FILTER_USERNAME 0x01 /* username */