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
];
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
) {
41 r
= test_password_many(hr
->hashed_password
, *pp
);
44 if (r
== 0) /* This is an old password as it isn't listed in the hashedPassword field, skip it */
47 /* Check this password against all old passwords */
48 STRV_FOREACH(old
, secret
->password
) {
53 r
= test_password_many(hr
->hashed_password
, *old
);
56 if (r
> 0) /* This is a new password, not suitable as old password */
59 r
= sym_pwquality_check(pwq
, *pp
, *old
, hr
->user_name
, &auxerror
);
61 return sd_bus_error_setf(error
, BUS_ERROR_LOW_PASSWORD_QUALITY
, "Password too weak: %s",
62 sym_pwquality_strerror(buf
, sizeof(buf
), r
, auxerror
));
70 /* If there are no old passwords, let's call pwquality_check() without any. */
71 r
= sym_pwquality_check(pwq
, *pp
, NULL
, hr
->user_name
, &auxerror
);
73 return sd_bus_error_setf(error
, BUS_ERROR_LOW_PASSWORD_QUALITY
, "Password too weak: %s",
74 sym_pwquality_strerror(buf
, sizeof(buf
), r
, auxerror
));
82 int user_record_quality_check_password(
85 sd_bus_error
*error
) {