This also switches all these notes to be defined via SD_ELF_NOTE_DLOPEN_ANCHORED(). Consequently, any notes added within unreachable or unused functions will be automatically garbage-collected by the linker (--gc-sections) instead of bloating the final binary. E.g. unused p11-kit library dependency is now dropped from systemd-repart.standalone binary. Before: ``` $ systemd-analyze dlopen-metadata build/systemd-repart.standalone FEATURE DESCRIPTION SONAME PRIORITY cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12 recommended blkid Support for block device identification libblkid.so.1 required libcrypto Support for cryptographic operations libcrypto.so.4 libcrypto.so.3 recommended mount Support for mount enumeration libmount.so.1 required fdisk Support for reading and writing partition tables libfdisk.so.1 required blkid Support for block device identification libblkid.so.1 recommended libcrypto Support for cryptographic operations libcrypto.so.4 libcrypto.so.3 suggested cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12 suggested fdisk Support for reading and writing partition tables libfdisk.so.1 suggested idn Support for internationalized domain names libidn2.so.0 suggested mount Support for mount enumeration libmount.so.1 recommended selinux Support for SELinux libselinux.so.1 recommended tpm Support for TPM libtss2-esys.so.0 suggested tpm Support for TPM libtss2-rc.so.0 suggested tpm Support for TPM libtss2-mu.so.0 suggested tpm Support for TPM libtss2-tcti-device.so.0 suggested p11-kit Support for PKCS11 hardware tokens libp11-kit.so.0 suggested ``` After: ``` $ systemd-analyze dlopen-metadata build/systemd-repart.standalone FEATURE DESCRIPTION SONAME PRIORITY cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12 recommended blkid Support for block device identification libblkid.so.1 required libcrypto Support for cryptographic operations libcrypto.so.4 libcrypto.so.3 recommended mount Support for mount enumeration libmount.so.1 required fdisk Support for reading and writing partition tables libfdisk.so.1 required blkid Support for block device identification libblkid.so.1 recommended libcrypto Support for cryptographic operations libcrypto.so.4 libcrypto.so.3 suggested cryptsetup Support for disk encryption, integrity, and authentication libcryptsetup.so.12 suggested fdisk Support for reading and writing partition tables libfdisk.so.1 suggested mount Support for mount enumeration libmount.so.1 recommended selinux Support for SELinux libselinux.so.1 recommended tpm Support for TPM libtss2-esys.so.0 suggested tpm Support for TPM libtss2-rc.so.0 suggested tpm Support for TPM libtss2-mu.so.0 suggested tpm Support for TPM libtss2-tcti-device.so.0 suggested ```
120 lines
5.0 KiB
C
120 lines
5.0 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#pragma once
|
|
|
|
#include "dlopen-note.h"
|
|
#include "shared-forward.h"
|
|
|
|
#if HAVE_PAM
|
|
#ifndef SYSTEMD_CFLAGS_MARKER_LIBPAM
|
|
# error "missing libpam_cflags in meson dependency."
|
|
#endif
|
|
|
|
#include <security/pam_appl.h>
|
|
#include <security/pam_ext.h>
|
|
#include <security/pam_modules.h> /* IWYU pragma: export */
|
|
#include <syslog.h>
|
|
|
|
#include "dlfcn-util.h"
|
|
|
|
extern DLSYM_PROTOTYPE(pam_acct_mgmt);
|
|
extern DLSYM_PROTOTYPE(pam_close_session);
|
|
extern DLSYM_PROTOTYPE(pam_end);
|
|
extern DLSYM_PROTOTYPE(pam_get_authtok_noverify);
|
|
extern DLSYM_PROTOTYPE(pam_get_authtok_verify);
|
|
extern DLSYM_PROTOTYPE(pam_get_data);
|
|
extern DLSYM_PROTOTYPE(pam_get_item);
|
|
extern DLSYM_PROTOTYPE(pam_get_user);
|
|
extern DLSYM_PROTOTYPE(pam_getenv);
|
|
extern DLSYM_PROTOTYPE(pam_getenvlist);
|
|
extern DLSYM_PROTOTYPE(pam_open_session);
|
|
extern DLSYM_PROTOTYPE(pam_prompt);
|
|
extern DLSYM_PROTOTYPE(pam_putenv);
|
|
extern DLSYM_PROTOTYPE(pam_set_data);
|
|
extern DLSYM_PROTOTYPE(pam_set_item);
|
|
extern DLSYM_PROTOTYPE(pam_setcred);
|
|
extern DLSYM_PROTOTYPE(pam_start);
|
|
extern DLSYM_PROTOTYPE(pam_strerror);
|
|
extern DLSYM_PROTOTYPE(pam_syslog);
|
|
extern DLSYM_PROTOTYPE(pam_vsyslog);
|
|
|
|
/* sym_pam_prompt() replacement for the pam_info() macro from <security/pam_ext.h>, which expands to a direct
|
|
* pam_prompt() call. */
|
|
#define sym_pam_info(pamh, fmt, ...) \
|
|
sym_pam_prompt((pamh), PAM_TEXT_INFO, NULL, (fmt), ## __VA_ARGS__)
|
|
|
|
void pam_log_setup(void);
|
|
|
|
int errno_to_pam_error(int error) _const_;
|
|
|
|
int pam_syslog_errno(pam_handle_t *pamh, int level, int error, const char *format, ...) _printf_(4,5);
|
|
|
|
int pam_syslog_pam_error(pam_handle_t *pamh, int level, int error, const char *format, ...) _printf_(4,5);
|
|
|
|
/* Call sym_pam_syslog if debug is enabled */
|
|
#define pam_debug_syslog(handle, debug, fmt, ...) \
|
|
({ \
|
|
if (debug) \
|
|
sym_pam_syslog(handle, LOG_DEBUG, fmt, ## __VA_ARGS__); \
|
|
})
|
|
|
|
/* Call pam_syslog_errno if debug is enabled */
|
|
#define pam_debug_syslog_errno(handle, debug, error, fmt, ...) \
|
|
({ \
|
|
int _error = (error); \
|
|
debug ? \
|
|
pam_syslog_errno(handle, LOG_DEBUG, _error, fmt, ## __VA_ARGS__) : \
|
|
errno_to_pam_error(_error); \
|
|
})
|
|
|
|
static inline int pam_log_oom(pam_handle_t *pamh) {
|
|
/* This is like log_oom(), but uses PAM logging */
|
|
return pam_syslog_errno(pamh, LOG_ERR, ENOMEM, "Out of memory.");
|
|
}
|
|
|
|
static inline int pam_bus_log_create_error(pam_handle_t *pamh, int r) {
|
|
/* This is like bus_log_create_error(), but uses PAM logging */
|
|
return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to create bus message: %m");
|
|
}
|
|
|
|
static inline int pam_bus_log_parse_error(pam_handle_t *pamh, int r) {
|
|
/* This is like bus_log_parse_error(), but uses PAM logging */
|
|
return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to parse bus message: %m");
|
|
}
|
|
|
|
typedef struct PamBusData PamBusData;
|
|
void pam_bus_data_disconnectp(PamBusData **d);
|
|
|
|
/* Use a different module name per different PAM module. They are all loaded in the same namespace, and this
|
|
* helps avoid a clash in the internal data structures of sd-bus. It will be used as key for cache items. */
|
|
int pam_acquire_bus_connection(
|
|
pam_handle_t *pamh,
|
|
const char *module_name,
|
|
bool debug,
|
|
sd_bus **ret_bus,
|
|
PamBusData **ret_pam_bus_data);
|
|
int pam_get_bus_data(pam_handle_t *pamh, const char *module_name, PamBusData **ret);
|
|
|
|
void pam_cleanup_free(pam_handle_t *pamh, void *data, int error_status);
|
|
void pam_cleanup_close(pam_handle_t *pamh, void *data, int error_status);
|
|
|
|
int pam_get_item_many_internal(pam_handle_t *pamh, ...);
|
|
#define pam_get_item_many(handle, ...) pam_get_item_many_internal(handle, __VA_ARGS__, -1)
|
|
|
|
int pam_get_data_many_internal(pam_handle_t *pamh, ...) _sentinel_;
|
|
#define pam_get_data_many(handle, ...) pam_get_data_many_internal(handle, __VA_ARGS__, NULL)
|
|
|
|
int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, const char *fmt, ...) _printf_(4,5);
|
|
|
|
/* Equivalent of pam_misc_setenv(pamh, name, value, 0), without the libpam_misc dep — builds "name=value"
|
|
* and hands it to sym_pam_putenv(), then erases the buffer before freeing in case it carried a secret. */
|
|
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value);
|
|
#endif
|
|
|
|
int dlopen_libpam(int log_level);
|
|
|
|
#define DLOPEN_LIBPAM(log_level, priority) \
|
|
({ \
|
|
LIBPAM_NOTE(priority); \
|
|
dlopen_libpam(log_level); \
|
|
})
|