Hide Forgot
Description of problem: timestamps are printed incorrectly 1. File uploaded during DST hours. Example timezone of the server was set to Europe/Amsterdam Time on the server was 21 Sep 2010 07:00 CEST [DST hour's for this timezone] File is uploaded on the server at 21 Sep @ 07:01 Example -rw-r--r--. 1 rrajaram rrajaram 841 Sep 21 07:01 vgdisplay 2. DST period is over and the current system time is Tue Jan 18 06:59:09 CET 2011 3. vsftpd has the following configuration use_localtime=YES/NO use_localtime if set to no(default), it sets to use GMT timezone instead of the localtime zone use_localtime if set to yes, it uses the system timezone 4. observer the time difference shown in both the cases from the client side after login [Server controls the timestamp] lsoutput taken from the server -rw-r--r-- 1 rrajaram rrajaram 841 Sep 21 07:01 vgdisplay VSFTPD configured with use_localtime=no [System is currently out of DST period] -rw-r--r-- 1 500 500 841 Sep 21 05:01 vgdisplay VSFTPD configured with use_localtime=yes [System is currently out of DST period] -rw-r--r-- 1 500 500 841 Sep 21 06:01 vgdisplay In above output, I believe second one is correct. vsftpd checks whether the file was uploaded during DST hour's and adjust the timestamp according to it in the aove first output, when vsftpd uses GMT timezone, difference is 2 hours. Is this correct behavior. Is logic wrong vsftpd just checks whether the file was uploaded during DST hour's and compares with the current GMT and says two hours difference How reproducible: always Additional info: Central European Standard Time = GMT+1 Central European Summer Time = GMT+2 gmtime works fine. the time returned by localtime seems to be the issue. localtime returned by ls ( from vsftpd) and by ls are different even after a service restart. from ./sysutil.c 1340 const char* 1341 vsf_sysutil_statbuf_get_date(const struct vsf_sysutil_statbuf* p_statbuf, 1342 int use_localtime) 1343 { ... 1350 if (!use_localtime) 1351 { 1352 p_tm = gmtime(&p_stat->st_mtime); 1353 } 1354 else 1355 { 1356 p_tm = localtime(&p_stat->st_mtime); 1357 } ... 1364 retval = strftime(datebuf, sizeof(datebuf), p_date_format, p_tm); from ./sysutil.c 2515 void 2516 vsf_sysutil_tzset(void) 2517 { 2518 int retval; 2519 char tzbuf[sizeof("+HHMM!")]; 2520 time_t the_time = time(NULL); 2521 struct tm* p_tm; 2522 tzset(); 2523 p_tm = localtime(&the_time); 2524 if (p_tm == NULL) 2525 { 2526 die("localtime"); 2527 } 2528 /* Set our timezone in the TZ environment variable to cater for the fact 2529 * that modern glibc does not cache /etc/localtime (which becomes inaccessible 2530 * when we chroot(). 2531 */ 2532 retval = strftime(tzbuf, sizeof(tzbuf), "%z", p_tm); 2533 tzbuf[sizeof(tzbuf) - 1] = '\0'; 2534 if (retval == 5) 2535 { 2536 /* Static because putenv() does not copy the string. */ 2537 static char envtz[sizeof("TZ=UTC-hh:mm")]; 2538 /* Insert a colon so we have e.g. -05:00 instead of -0500 */ 2539 tzbuf[5] = tzbuf[4]; 2540 tzbuf[4] = tzbuf[3]; 2541 tzbuf[3] = ':'; 2542 /* Invert the sign - we just got the offset _from_ UTC but for TZ, we need 2543 * the offset _to_ UTC. 2544 */ 2545 if (tzbuf[0] == '+') 2546 { 2547 tzbuf[0] = '-'; 2548 } 2549 else 2550 { 2551 tzbuf[0] = '+'; 2552 } 2553 snprintf(envtz, sizeof(envtz), "TZ=UTC%s", tzbuf); 2554 putenv(envtz); <--- We set up the TZ based on UTC, as we have no access to "/etc/localtime" under chroot environment <--- this leads to bad mojo 2555 s_timezone = ((tzbuf[1] - '0') * 10 + (tzbuf[2] - '0')) * 60 * 60; 2556 s_timezone += ((tzbuf[4] - '0') * 10 + (tzbuf[5] - '0')) * 60; 2557 if (tzbuf[0] == '-') 2558 { 2559 s_timezone *= -1; 2560 } 2561 } 2562 } 2563
(In reply to comment #0) > 2553 snprintf(envtz, sizeof(envtz), "TZ=UTC%s", tzbuf); > 2554 putenv(envtz); > <--- We set up the TZ based on UTC, as we have no access to "/etc/localtime" > under chroot environment > <--- this leads to bad mojo > That's right. TZ environmental variable affects results of localtime(). Mtime that is out of current DST state is corrupted.
Created attachment 488131 [details] patch fixing this issue Vsftpd currently fills TZ environmental variable without DST specification. This leads to incorrect interpretation mtime value of the files that were last modified before latest DST change. This patch uses content of /etc/localtime to fill up TZ inclusive DST definition.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHBA-2011-0830.html