Description of problem: In gssftpd (part of the krb5-workstation) RPM does a chroot() when an anonymous login session is started. However, the logs it writes (the file is opened previous to the chroot()) gets written with timestamps (from ctime() in ftpd.c:dolog()). The problem is that all logs after the chroot() get written as GMT, since ctime() no longer has access to the contents of /etc/localtime. At a minimum, either a hook to prefect and store the contents of /etc/localtime could be added, or else the man page could be explain the interaction of chroot() with ctime(), and the importance of calling ctime() to prime its state before the chroot(). Version-Release number of selected component (if applicable): 2.4-11 How reproducible: Compile and run the attached file. If compiled with -DBEFORE, it works properly. If compiled without it, it doesn't. (Note: must be run as root because of the chroot() in it.) Actual results: Sun Nov 26 23:54:44 2006 Expected results: Sun Nov 26 16:54:44 2006 Additional info:
Created attachment 142142 [details] Sample test program.
Most of this is documented already in POSIX. The "hook to prefetch /etc/localtime" is called tzset(3p), then there are several functions which just use the timezone data (these do effectively an tzset only if it hasn't been called yet in the current process, ctime is one of them) and then other function where their 3p section man pages mention that they behave as if they use tzset internally (e.g. localtime, these functions really do that). If TZ env var is unset, tzset stats /etc/localtime and if it was called the first time or if it changed since last call (this was added so that changing timezone on a running system is possible without restarting everything), it is reread (and if /etc/localtime is not valid, the default is TZ=GMT). So, when using the chroot, preferrably link or bind mount /etc/localtime into the chroot (e.g. system-config-date and /usr/sbin/tzdata-update copy /etc/localtime over to /var/spool/postfix/etc/localtime if it existed previously and had the same content as /etc/localtime), or tzset () before chrooting and make sure you don't use any functions where documentation says it behaves as if tzset () was called.
Ok, does localtime_r() behave like localtime() in this respect? Does ctime_r() behave local ctime()? And does openlog() call tzset() to make itself chroot()-safe? If not, it might be worth changing it so that it does. But I guess the more important issue, is that when it is called repeatedly (as happens in glibc's syslog() -- since it calls localtime_r() and strftime_r()), should it be idempotent? If you call it outside the chroot() prison, and tzset() succeeds, then you chroot() and call it again and it fails to find its files... should failing cause it to clobber the previously good results it had from before? Seems self-defeating.