-
Notifications
You must be signed in to change notification settings - Fork 223
Commit
The third field in the /etc/shadow file (sp_lstchg) contains the date of the last password change expressed as the number of days since Jan 1, 1970. As this is a relative time, creating a user today will result in: username:17238:0:99999:7::: whilst creating the same user tomorrow will result in: username:17239:0:99999:7::: This has an impact for the Reproducible Builds[0] project where we aim to be independent of as many elements the build environment as possible, including the current date. This patch changes the behaviour to use the SOURCE_DATE_EPOCH[1] environment variable (instead of Jan 1, 1970) if valid. [0] https://reproducible-builds.org/ [1] https://reproducible-builds.org/specs/source-date-epoch/ Signed-off-by: Chris Lamb <lamby@debian.org>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright (c) 2017, Chris Lamb | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions | ||
* are met: | ||
* 1. Redistributions of source code must retain the above copyright | ||
* notice, this list of conditions and the following disclaimer. | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* 3. The name of the copyright holders or contributors may not be used to | ||
* endorse or promote products derived from this software without | ||
* specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
* HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
*/ | ||
|
||
#include <config.h> | ||
|
||
#ident "$Id$" | ||
|
||
#include <errno.h> | ||
#include <limits.h> | ||
#include <stdio.h> | ||
#include "defines.h" | ||
#include "prototypes.h" | ||
|
||
/* | ||
* gettime() returns the time as the number of seconds since the Epoch | ||
* | ||
* Like time(), gettime() returns the time as the number of seconds since the | ||
* Epoch, 1970-01-01 00:00:00 +0000 (UTC), except that if the SOURCE_DATE_EPOCH | ||
* environment variable is exported it will use that instead. | ||
*/ | ||
/*@observer@*/time_t gettime () | ||
{ | ||
char *endptr; | ||
char *source_date_epoch; | ||
time_t fallback; | ||
unsigned long long epoch; | ||
|
||
fallback = time (NULL); | ||
source_date_epoch = getenv ("SOURCE_DATE_EPOCH"); | ||
|
||
if (!source_date_epoch) | ||
return fallback; | ||
|
||
errno = 0; | ||
epoch = strtoull (source_date_epoch, &endptr, 10); | ||
if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0)) | ||
|| (errno != 0 && epoch == 0)) { | ||
fprintf (stderr, | ||
_("Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n"), | ||
strerror(errno)); | ||
} else if (endptr == source_date_epoch) { | ||
fprintf (stderr, | ||
_("Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n"), | ||
endptr); | ||
} else if (*endptr != '\0') { | ||
fprintf (stderr, | ||
_("Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n"), | ||
endptr); | ||
} else if (epoch > ULONG_MAX) { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
lamby
Author
Contributor
|
||
fprintf (stderr, | ||
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to %lu but was found to be: %llu\n"), | ||
ULONG_MAX, epoch); | ||
} else if (epoch > fallback) { | ||
fprintf (stderr, | ||
_("Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to the current time (%lu) but was found to be: %llu\n"), | ||
fallback, epoch); | ||
} else { | ||
/* Valid */ | ||
return (time_t)epoch; | ||
} | ||
|
||
return fallback; | ||
} |
Was there any reason to reject
>ULONG_MAX
? I'm touching this code, and don't see a reason for it; it looks very arbitrary; especially since some systems can have 32-bit long, but 64-bit time_t. Should I just drop that check, or keep it? And why?Cc: @lamby , @hallyn