summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBaptiste Daroussin <bapt@FreeBSD.org>2015-07-05 09:48:03 +0000
committerBaptiste Daroussin <bapt@FreeBSD.org>2015-07-05 09:48:03 +0000
commitede1c7addbd047595d4ca1701f0d4f9b143694ed (patch)
tree54ff1bf0f8e84899345fc0a865e84db115196e86
parent61380b9ab922279f463e451be86a4f9515d8003d (diff)
downloadpw-darwin-ede1c7addbd047595d4ca1701f0d4f9b143694ed.tar.gz
pw-darwin-ede1c7addbd047595d4ca1701f0d4f9b143694ed.tar.zst
pw-darwin-ede1c7addbd047595d4ca1701f0d4f9b143694ed.zip
Validate expiration dates
Use strptime_l(3) to validate the dates provided in input
-rw-r--r--pw/psdate.c65
-rwxr-xr-xpw/tests/pw_useradd.sh26
2 files changed, 55 insertions, 36 deletions
diff --git a/pw/psdate.c b/pw/psdate.c
index 3f4c010..b43315b 100644
--- a/pw/psdate.c
+++ b/pw/psdate.c
@@ -33,6 +33,8 @@ static const char rcsid[] =
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
+#include <xlocale.h>
+#include <err.h>
#include "psdate.h"
@@ -95,16 +97,6 @@ weekday(char const ** str)
return aindex(days, str, 3);
}
-static int
-month(char const ** str)
-{
- static char const *months[] =
- {"jan", "feb", "mar", "apr", "may", "jun", "jul",
- "aug", "sep", "oct", "nov", "dec", NULL};
-
- return aindex(months, str, 3);
-}
-
static void
parse_time(char const * str, int *hour, int *min, int *sec)
{
@@ -122,34 +114,35 @@ parse_time(char const * str, int *hour, int *min, int *sec)
static void
parse_datesub(char const * str, int *day, int *mon, int *year)
{
- int i;
+ struct tm tm;
+ locale_t l;
+ int i;
+ char *ret;
+ const char *valid_formats[] = {
+ "%d-%b-%y",
+ "%d-%b-%Y",
+ "%d-%m-%y",
+ "%d-%m-%Y",
+ NULL,
+ };
+
+ l = newlocale(LC_ALL_MASK, "C", NULL);
+
+ memset(&tm, 0, sizeof(tm));
+ for (i=0; valid_formats[i] != NULL; i++) {
+ ret = strptime_l(str, valid_formats[i], &tm, l);
+ if (ret && *ret == '\0') {
+ *day = tm.tm_mday;
+ *mon = tm.tm_mon;
+ *year = tm.tm_year;
+ freelocale(l);
+ return;
+ }
+ }
- static char const nchrs[] = "0123456789 \t,/-.";
+ freelocale(l);
- if ((i = month(&str)) != -1) {
- *mon = i;
- if ((i = a2i(&str)) != 0)
- *day = i;
- } else if ((i = a2i(&str)) != 0) {
- *day = i;
- while (*str && strchr(nchrs + 10, *str) != NULL)
- ++str;
- if ((i = month(&str)) != -1)
- *mon = i;
- else if ((i = a2i(&str)) != 0)
- *mon = i - 1;
- } else
- return;
-
- while (*str && strchr(nchrs + 10, *str) != NULL)
- ++str;
- if (isdigit((unsigned char)*str)) {
- *year = atoi(str);
- if (*year > 1900)
- *year -= 1900;
- else if (*year < 32)
- *year += 100;
- }
+ errx(EXIT_FAILURE, "Invalid date");
}
diff --git a/pw/tests/pw_useradd.sh b/pw/tests/pw_useradd.sh
index 27a8624..93cde50 100755
--- a/pw/tests/pw_useradd.sh
+++ b/pw/tests/pw_useradd.sh
@@ -176,6 +176,31 @@ user_add_name_too_long_body() {
${PW} useradd name_very_vert_very_very_very_long
}
+atf_test_case user_add_expiration
+user_add_expiration_body() {
+ populate_etc_skel
+
+ atf_check -s exit:0 \
+ ${PW} useradd foo -e 20-03-2043
+ atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \
+ -s exit:0 grep "^foo" ${HOME}/master.passwd
+ atf_check -s exit:0 ${PW} userdel foo
+ atf_check -s exit:0 \
+ ${PW} useradd foo -e 20-03-43
+ atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \
+ -s exit:0 grep "^foo" ${HOME}/master.passwd
+ atf_check -s exit:0 ${PW} userdel foo
+ atf_check -s exit:0 \
+ ${PW} useradd foo -e 20-Mar-2043
+ atf_check -o inline:"foo:*:1001:1001::0:2310422400:User &:/home/foo:/bin/sh\n" \
+ -s exit:0 grep "^foo" ${HOME}/master.passwd
+ atf_check -s exit:0 ${PW} userdel foo
+ atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
+ ${PW} useradd foo -e 20-Foo-2043
+ atf_check -e inline:"pw: Invalid date\n" -s exit:1 \
+ ${PW} useradd foo -e 20-13-2043
+}
+
atf_init_test_cases() {
atf_add_test_case user_add
atf_add_test_case user_add_noupdate
@@ -193,4 +218,5 @@ atf_init_test_cases() {
atf_add_test_case user_add_password_expiration_date_month
atf_add_test_case user_add_password_expiration_date_relative
atf_add_test_case user_add_name_too_long
+ atf_add_test_case user_add_expiration
}