Problem:
Programs running inside chroot(2) jail can not access system time zone definition from '/etc/localtime'
or other time zone data directories such as '/usr/share/zoneinfo/'. As a result, these programs rely on
the POSIX TZ environment variable for accessing system time zone definition.
See:
vsftpd: vsf_sysutil_tzset(void) -> ../vsftpd-3.0.2/sysutil.c
postfix: -> http://www.postfix.org/postconf.5.html (search "TZ")
In the absence of TZ, applications either fall back to UTC times or report incorrect times.
Currently, there is no standard method for a user to query current system time zone definition
and appropriately set the TZ environment variable, as:
- TZ="NZST-12:00:00NZDT-13:00:00,M10.1.0,M3.3.0"
Solutions:
There are multiple ways to address this problem:
Introduction of a new API to query current system time zone definition.
-> https://bugzilla.redhat.com/show_bug.cgi?id=1077902
The new API could:- return TZ string at the end of time zone data file. Sometimes this string is not present.
- return ":/path/to/time/zone/data/file" and assume it is accessible. It requires matching tzdata.
return absolute path to the zoneinfo file. Should resolve under new root directory.
- encoded copy of the zoneinfo file. It would require libc that can read this.
return an opaque token; Like a uuid with version for each zone.
Opaque token requires coordination with tzdata.
To copy '/etc/localtime' to the new 'root' directory.
This may not be always possible and somehow does not work.To copy contents of '/etc/localtime' to TZ environment variable.
This too may not be possible for the size constraints on the environment memory space.TZ service that would return the current system time zone.
If TZ service could operate like ntp, it would be quite nice.
It would work but may be an overkill.Ask user to appropriately set TZ environment variable or fall back to
using UTC when TZ is unset.Use existing APIs to gather information about the current time zone,
construct a POSIX-TZ-enviroment-variable-style string and use that for
the chroot's TZ value. Again this is inaccurate because it doesn't have
enough information.Extend tzalloc() by reserving a "localtime" keyword to mean "give me the
current zone info." resulting in an object we could use for further
manipulation to pass to a chroot'd process. This also means you can use
the 'z' variant APIs for the local or non-local tz's all the same just by
using the reserved "localtime" keyword. For example- char * tzget (const timezone_t tz); // Where the string is usable with TZ.
Note: tzgetname or tzgetzone (typo) are not usable for the purposes
of discovering the name of the timezone being currently used.
Just read the rather interesting historical read :-)
-> http://www.cl.cam.ac.uk/~mgk25/time/c/comment-eggert.html