aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_unix/support.c
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2023-12-10 14:20:32 +0000
committerTobias Stoeckmann <tobias@stoeckmann.org>2023-12-11 21:02:31 +0100
commitb8429cc8036cd23d075174d13eedc6d857e2b454 (patch)
tree961a80706e4bfa229cfe0c9ec127b28da7fe4fe4 /modules/pam_unix/support.c
parentbf9ebc84c091f9f2d018aac2f9c2c4c4933e319e (diff)
downloadpam-b8429cc8036cd23d075174d13eedc6d857e2b454.tar.gz
pam-b8429cc8036cd23d075174d13eedc6d857e2b454.tar.bz2
pam-b8429cc8036cd23d075174d13eedc6d857e2b454.zip
pam_unix: check str to integer conversions
Print an error in syslog if an integer could not be converted. Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Diffstat (limited to 'modules/pam_unix/support.c')
-rw-r--r--modules/pam_unix/support.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index ec9a5725..9cc39ad7 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -46,6 +46,18 @@ int _make_remark(pam_handle_t * pamh, unsigned long long ctrl,
return retval;
}
+static int _unix_strtoi(const char *str, int minval, int *result)
+{
+ char *ep;
+ long value = strtol(str, &ep, 10);
+ if (value < minval || value > INT_MAX || str == ep || *ep != '\0') {
+ *result = minval;
+ return -1;
+ }
+ *result = (int)value;
+ return 0;
+}
+
/*
* set the control flags for the UNIX module.
*/
@@ -126,9 +138,11 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember,
"option remember not allowed for this module type");
continue;
}
- *remember = strtol(str, NULL, 10);
- if ((*remember == INT_MIN) || (*remember == INT_MAX))
- *remember = -1;
+ if (_unix_strtoi(str, -1, remember)) {
+ pam_syslog(pamh, LOG_ERR,
+ "option remember invalid [%s]", str);
+ continue;
+ }
if (*remember > 400)
*remember = 400;
} else if (j == UNIX_MIN_PASS_LEN) {
@@ -137,14 +151,22 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember,
"option minlen not allowed for this module type");
continue;
}
- *pass_min_len = atoi(str);
+ if (_unix_strtoi(str, 0, pass_min_len)) {
+ pam_syslog(pamh, LOG_ERR,
+ "option minlen invalid [%s]", str);
+ continue;
+ }
} else if (j == UNIX_ALGO_ROUNDS) {
if (rounds == NULL) {
pam_syslog(pamh, LOG_ERR,
"option rounds not allowed for this module type");
continue;
}
- *rounds = strtol(str, NULL, 10);
+ if (_unix_strtoi(str, 0, rounds)) {
+ pam_syslog(pamh, LOG_ERR,
+ "option rounds invalid [%s]", str);
+ continue;
+ }
}
ctrl &= unix_args[j].mask; /* for turning things off */
@@ -166,16 +188,24 @@ unsigned long long _set_ctrl(pam_handle_t *pamh, int flags, int *remember,
/* Read number of rounds for sha256, sha512 and yescrypt */
if (off(UNIX_ALGO_ROUNDS, ctrl) && rounds != NULL) {
- val = NULL;
- if (on(UNIX_YESCRYPT_PASS, ctrl)) {
- val = pam_modutil_search_key(pamh, LOGIN_DEFS, "YESCRYPT_COST_FACTOR");
- } else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) {
- val = pam_modutil_search_key(pamh, LOGIN_DEFS, "SHA_CRYPT_MAX_ROUNDS");
- }
- if (val) {
- *rounds = strtol(val, NULL, 10);
- set(UNIX_ALGO_ROUNDS, ctrl);
- free (val);
+ const char *key = NULL;
+ if (on(UNIX_YESCRYPT_PASS, ctrl))
+ key = "YESCRYPT_COST_FACTOR";
+ else if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl))
+ key = "SHA_CRYPT_MAX_ROUNDS";
+ else
+ key = NULL;
+
+ if (key != NULL) {
+ val = pam_modutil_search_key(pamh, LOGIN_DEFS, key);
+ if (val) {
+ if (_unix_strtoi(val, 0, rounds))
+ pam_syslog(pamh, LOG_ERR,
+ "option %s invalid [%s]", key, val);
+ else
+ set(UNIX_ALGO_ROUNDS, ctrl);
+ free (val);
+ }
}
}