https://fedorahosted.org/sssd/ticket/1712
From bb0fe03141cc18041633fa2cce7605349c0b4a16 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <[email protected]>
Date: Wed, 12 Dec 2012 14:11:11 +0100
Subject: [PATCH] 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.
---
 src/db/sysdb_sudo.c | 45 ++++++++++++++++++++++++++++++++++-----------
 src/db/sysdb_sudo.h |  2 --
 2 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/src/db/sysdb_sudo.c b/src/db/sysdb_sudo.c
index 39b1504da4e1c2ea4cc4e806f430f5adde3e9f3b..56a34a6aa9890a6814ec44ee95d8ae1b4421a8dd 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 35b350c6370b0f199064766b2a789a0c2fffa6ca..f37afff8c4a0b79ac7626f737aa24deb99af93ec 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             */
-- 
1.7.11.7

_______________________________________________
sssd-devel mailing list
[email protected]
https://lists.fedorahosted.org/mailman/listinfo/sssd-devel

Reply via email to