]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/login/pam_systemd_loadkey.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <security/_pam_macros.h>
5 #include <security/pam_ext.h>
6 #include <security/pam_misc.h>
7 #include <security/pam_modules.h>
8 #include <security/pam_modutil.h>
10 #include "keyring-util.h"
12 #include "missing_syscall.h"
13 #include "nulstr-util.h"
17 /* By default, this module retrieves the key stored by systemd-cryptsetup.
18 * This can be overridden by the keyname= parameter. */
19 static const char DEFAULT_KEYNAME
[] = "cryptsetup";
21 _public_ PAM_EXTERN
int pam_sm_authenticate(
24 int argc
, const char **argv
) {
33 assert(argc
== 0 || argv
);
35 const char *keyname
= DEFAULT_KEYNAME
;
38 for (int i
= 0; i
< argc
; i
++) {
41 if ((p
= startswith(argv
[i
], "keyname=")))
43 else if (streq(argv
[i
], "debug"))
46 pam_syslog(handle
, LOG_WARNING
, "Unknown parameter '%s', ignoring.", argv
[i
]);
49 pam_debug_syslog(handle
, debug
, "pam-systemd-loadkey initializing");
51 /* Retrieve the key. */
54 serial
= request_key("user", keyname
, NULL
, 0);
56 if (errno
== ENOKEY
) {
57 pam_debug_syslog(handle
, debug
, "Key not found: %s", keyname
);
58 return PAM_AUTHINFO_UNAVAIL
;
59 } else if (errno
== EKEYEXPIRED
) {
60 pam_debug_syslog(handle
, debug
, "Key expired: %s", keyname
);
61 return PAM_AUTHINFO_UNAVAIL
;
63 return pam_syslog_errno(handle
, LOG_ERR
, errno
, "Failed to look up the key: %m");
66 _cleanup_(erase_and_freep
) void *p
= NULL
;
70 r
= keyring_read(serial
, &p
, &n
);
72 return pam_syslog_errno(handle
, LOG_ERR
, r
, "Failed to read the key: %m");
74 /* Split the key by NUL. Set the last item as authtok. */
76 _cleanup_(strv_free_erasep
) char **passwords
= strv_parse_nulstr(p
, n
);
78 return pam_log_oom(handle
);
80 size_t passwords_len
= strv_length(passwords
);
81 if (passwords_len
== 0) {
82 pam_debug_syslog(handle
, debug
, "Key is empty");
83 return PAM_AUTHINFO_UNAVAIL
;
84 } else if (passwords_len
> 1)
85 pam_debug_syslog(handle
, debug
, "Multiple passwords found in the key. Using the last one");
87 r
= pam_set_item(handle
, PAM_AUTHTOK
, passwords
[passwords_len
- 1]);
89 return pam_syslog_pam_error(handle
, LOG_ERR
, r
, "Failed to set PAM auth token: @PAMERR@");
94 _public_ PAM_EXTERN
int pam_sm_setcred(
97 int argc
, const char **argv
) {