1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include "bus-common-errors.h"
4 #include "errno-util.h"
6 #include "libcrypt-util.h"
7 #include "pwquality-util.h"
9 #include "user-record-pwquality.h"
10 #include "user-record-util.h"
14 int user_record_quality_check_password(
17 sd_bus_error
*error
) {
19 _cleanup_(sym_pwquality_free_settingsp
) pwquality_settings_t
*pwq
= NULL
;
20 char buf
[PWQ_MAX_ERROR_MESSAGE_LEN
], **pp
;
27 r
= pwq_allocate_context(&pwq
);
28 if (ERRNO_IS_NOT_SUPPORTED(r
))
31 return log_debug_errno(r
, "Failed to allocate libpwquality context: %m");
33 /* This is a bit more complex than one might think at first. pwquality_check() would like to know the
34 * old password to make security checks. We support arbitrary numbers of passwords however, hence we
35 * call the function once for each combination of old and new password. */
37 /* Iterate through all new passwords */
38 STRV_FOREACH(pp
, secret
->password
) {
42 r
= test_password_many(hr
->hashed_password
, *pp
);
45 if (r
== 0) /* This is an old password as it isn't listed in the hashedPassword field, skip it */
48 /* Check this password against all old passwords */
49 STRV_FOREACH(old
, secret
->password
) {
54 r
= test_password_many(hr
->hashed_password
, *old
);
57 if (r
> 0) /* This is a new password, not suitable as old password */
60 r
= sym_pwquality_check(pwq
, *pp
, *old
, hr
->user_name
, &auxerror
);
62 return sd_bus_error_setf(error
, BUS_ERROR_LOW_PASSWORD_QUALITY
, "Password too weak: %s",
63 sym_pwquality_strerror(buf
, sizeof(buf
), r
, auxerror
));
71 /* If there are no old passwords, let's call pwquality_check() without any. */
72 r
= sym_pwquality_check(pwq
, *pp
, NULL
, hr
->user_name
, &auxerror
);
74 return sd_bus_error_setf(error
, BUS_ERROR_LOW_PASSWORD_QUALITY
, "Password too weak: %s",
75 sym_pwquality_strerror(buf
, sizeof(buf
), r
, auxerror
));
83 int user_record_quality_check_password(
86 sd_bus_error
*error
) {