lib/ldb: fix logic in ldb_val_to_time()
authorStefan Metzmacher <metze@samba.org>
Mon, 19 Jan 2015 14:47:58 +0000 (15:47 +0100)
committerStefan Metzmacher <metze@samba.org>
Sat, 24 Jan 2015 16:49:05 +0000 (17:49 +0100)
040408072012Z should represent 20040408072012.0Z
as well as 20040408072012.000Z or
20040408072012.RandomIgnoredCharaters...Z

Bug: https://bugzilla.samba.org/show_bug.cgi?id=9810

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
lib/ldb/common/ldb_msg.c

index 809e3af8193a9b7def5356db04220f5c5603a20f..3f65351ff293f0d656835038813372e26a9bbc36 100644 (file)
@@ -1090,28 +1090,54 @@ time_t ldb_string_to_time(const char *s)
 */
 int ldb_val_to_time(const struct ldb_val *v, time_t *t)
 {
-       struct tm tm;
+       char val[15] = {};
+       struct tm tm = {};
 
-       if (v == NULL || !v->data || (v->length != 17 && v->length != 13)) {
+       if (v == NULL) {
                return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
        }
 
-       memset(&tm, 0, sizeof(tm));
+       if (v->data == NULL) {
+               return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+       }
+
+       if (v->length < 16 && v->length != 13) {
+               return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+       }
+
+       if (v->data[v->length - 1] != 'Z') {
+               return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+       }
 
        if (v->length == 13) {
-               if (sscanf((char *)v->data, "%02u%02u%02u%02u%02u%02uZ",
+               memcpy(val, v->data, 12);
+
+               if (sscanf(val, "%02u%02u%02u%02u%02u%02u",
                        &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
                        &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
+               if (tm.tm_year < 50) {
+                       tm.tm_year += 100;
+               }
        } else {
-               if (sscanf((char *)v->data, "%04u%02u%02u%02u%02u%02u.0Z",
+
+               /*
+                * anything between '.' and 'Z' is silently ignored.
+                */
+               if (v->data[14] != '.') {
+                       return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
+               }
+
+               memcpy(val, v->data, 14);
+
+               if (sscanf(val, "%04u%02u%02u%02u%02u%02u",
                        &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
                        &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) {
                        return LDB_ERR_INVALID_ATTRIBUTE_SYNTAX;
                }
+               tm.tm_year -= 1900;
        }
-       tm.tm_year -= 1900;
        tm.tm_mon -= 1;
 
        *t = timegm(&tm);