dhclient: fix time parsing for leases expiring after 2038
Convert lease parsing to timegm to calculate timestamp. For reference, when writing the lease, we use gmtime to convert the timestamp to struct tm. Reviewed By: markj, vangyzen MFC after: 2 weeks Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D40760
This commit is contained in:
parent
6c049996ec
commit
c210cac00f
@ -444,9 +444,7 @@ convert_num(unsigned char *buf, char *str, unsigned base, int size)
|
|||||||
time_t
|
time_t
|
||||||
parse_date(FILE *cfile)
|
parse_date(FILE *cfile)
|
||||||
{
|
{
|
||||||
static int months[11] = { 31, 59, 90, 120, 151, 181,
|
int token;
|
||||||
212, 243, 273, 304, 334 };
|
|
||||||
int guess, token;
|
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
char *val;
|
char *val;
|
||||||
|
|
||||||
@ -570,27 +568,5 @@ parse_date(FILE *cfile)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Guess the time value... */
|
return (timegm(&tm));
|
||||||
guess = ((((((365 * (tm.tm_year - 70) + /* Days in years since '70 */
|
|
||||||
(tm.tm_year - 69) / 4 + /* Leap days since '70 */
|
|
||||||
(tm.tm_mon /* Days in months this year */
|
|
||||||
? months[tm.tm_mon - 1]
|
|
||||||
: 0) +
|
|
||||||
(tm.tm_mon > 1 && /* Leap day this year */
|
|
||||||
!((tm.tm_year - 72) & 3)) +
|
|
||||||
tm.tm_mday - 1) * 24) + /* Day of month */
|
|
||||||
tm.tm_hour) * 60) +
|
|
||||||
tm.tm_min) * 60) + tm.tm_sec;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This guess could be wrong because of leap seconds or other
|
|
||||||
* weirdness we don't know about that the system does. For
|
|
||||||
* now, we're just going to accept the guess, but at some point
|
|
||||||
* it might be nice to do a successive approximation here to get
|
|
||||||
* an exact value. Even if the error is small, if the server
|
|
||||||
* is restarted frequently (and thus the lease database is
|
|
||||||
* reread), the error could accumulate into something
|
|
||||||
* significant.
|
|
||||||
*/
|
|
||||||
return (guess);
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@ ATF_TESTS_SH= pcp
|
|||||||
|
|
||||||
PLAIN_TESTS_C= option-domain-search_test
|
PLAIN_TESTS_C= option-domain-search_test
|
||||||
SRCS.option-domain-search_test= alloc.c convert.c hash.c options.c \
|
SRCS.option-domain-search_test= alloc.c convert.c hash.c options.c \
|
||||||
tables.c fake.c option-domain-search.c
|
tables.c parse.c conflex.c tree.c fake.c \
|
||||||
|
option-domain-search.c
|
||||||
CFLAGS.option-domain-search_test+= -I${.CURDIR:H}
|
CFLAGS.option-domain-search_test+= -I${.CURDIR:H}
|
||||||
LIBADD.option-domain-search_test= util
|
LIBADD.option-domain-search_test= util
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "dhcpd.h"
|
#include "dhcpd.h"
|
||||||
|
|
||||||
extern jmp_buf env;
|
extern jmp_buf env;
|
||||||
|
int warnings_occurred;
|
||||||
|
|
||||||
void
|
void
|
||||||
error(const char *fmt, ...)
|
error(const char *fmt, ...)
|
||||||
@ -52,6 +53,20 @@ note(const char *fmt, ...)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
parse_warn(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
ret = vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
bootp(struct packet *packet)
|
bootp(struct packet *packet)
|
||||||
{
|
{
|
||||||
|
@ -303,6 +303,49 @@ multiple_domains_valid()
|
|||||||
free(option->data);
|
free(option->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
parse_date_helper(const char *string, time_t timestamp)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
FILE *file = NULL;
|
||||||
|
time_t ts;
|
||||||
|
|
||||||
|
file = fopen("/tmp/dhclient.test", "w");
|
||||||
|
if (!file)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
ret = fwrite(string, strlen(string), 1, file);
|
||||||
|
if (ret <= 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
file = fopen("/tmp/dhclient.test", "r");
|
||||||
|
if (!file)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
new_parse("test");
|
||||||
|
ts = parse_date(file);
|
||||||
|
if (ts != timestamp)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_date_valid(void)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = setjmp(env);
|
||||||
|
if (ret != 0)
|
||||||
|
abort();
|
||||||
|
|
||||||
|
parse_date_helper(" 2 2024/7/2 20:25:50;\n", 1719951950);
|
||||||
|
parse_date_helper(" 1 2091/7/2 20:25:50;\n", 3834246350);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@ -324,5 +367,7 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
multiple_domains_valid();
|
multiple_domains_valid();
|
||||||
|
|
||||||
|
parse_date_valid();
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user