return PAM_SUCCESS;
}
-static int pam_close_session_and_delete_credentials(pam_handle_t *handle, int flags) {
+static int pam_close_session_and_delete_credentials(pam_handle_t *pamh, int flags) {
int r, s;
- assert(handle);
+ assert(pamh);
- r = sym_pam_close_session(handle, flags);
+ r = sym_pam_close_session(pamh, flags);
if (r != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_DEBUG, r, "pam_close_session() failed: @PAMERR@");
+ pam_syslog_pam_error(pamh, LOG_DEBUG, r, "pam_close_session() failed: @PAMERR@");
- s = sym_pam_setcred(handle, PAM_DELETE_CRED | flags);
+ s = sym_pam_setcred(pamh, PAM_DELETE_CRED | flags);
if (s != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_DEBUG, r, "pam_setcred(PAM_DELETE_CRED) failed: @PAMERR@");
+ pam_syslog_pam_error(pamh, LOG_DEBUG, r, "pam_setcred(PAM_DELETE_CRED) failed: @PAMERR@");
return r != PAM_SUCCESS ? r : s;
}
_cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
_cleanup_strv_free_ char **e = NULL;
_cleanup_free_ char *tty = NULL;
- pam_handle_t *handle = NULL;
+ pam_handle_t *pamh = NULL;
sigset_t old_ss;
int pam_code = PAM_SUCCESS, r;
bool close_session = false;
if (log_get_max_level() < LOG_DEBUG)
flags |= PAM_SILENT;
- pam_code = sym_pam_start(context->pam_name, user, &conv, &handle);
+ pam_code = sym_pam_start(context->pam_name, user, &conv, &pamh);
if (pam_code != PAM_SUCCESS) {
- handle = NULL;
+ pamh = NULL;
goto fail;
}
if (r < 0)
goto fail;
if (r > 0) {
- pam_code = sym_pam_set_item(handle, PAM_TTY, tty);
+ pam_code = sym_pam_set_item(pamh, PAM_TTY, tty);
if (pam_code != PAM_SUCCESS)
goto fail;
}
STRV_FOREACH(nv, *env) {
- pam_code = sym_pam_putenv(handle, *nv);
+ pam_code = sym_pam_putenv(pamh, *nv);
if (pam_code != PAM_SUCCESS)
goto fail;
}
- pam_code = sym_pam_acct_mgmt(handle, flags);
+ pam_code = sym_pam_acct_mgmt(pamh, flags);
if (pam_code != PAM_SUCCESS)
goto fail;
- pam_code = sym_pam_setcred(handle, PAM_ESTABLISH_CRED | flags);
+ pam_code = sym_pam_setcred(pamh, PAM_ESTABLISH_CRED | flags);
if (pam_code != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_DEBUG, pam_code, "pam_setcred(PAM_ESTABLISH_CRED) failed, ignoring: @PAMERR@");
+ pam_syslog_pam_error(pamh, LOG_DEBUG, pam_code, "pam_setcred(PAM_ESTABLISH_CRED) failed, ignoring: @PAMERR@");
- pam_code = sym_pam_open_session(handle, flags);
+ pam_code = sym_pam_open_session(pamh, flags);
if (pam_code != PAM_SUCCESS)
goto fail;
close_session = true;
- e = sym_pam_getenvlist(handle);
+ e = sym_pam_getenvlist(pamh);
if (!e) {
pam_code = PAM_BUF_ERR;
goto fail;
/* If our parent died we'll end the session */
if (getppid() != parent_pid) {
- pam_code = pam_close_session_and_delete_credentials(handle, flags);
+ pam_code = pam_close_session_and_delete_credentials(pamh, flags);
if (pam_code != PAM_SUCCESS)
goto child_finish;
}
child_finish:
/* NB: pam_end() when called in child processes should set PAM_DATA_SILENT to let the module
* know about this. See pam_end(3) */
- (void) sym_pam_end(handle, pam_code | flags | PAM_DATA_SILENT);
+ (void) sym_pam_end(pamh, pam_code | flags | PAM_DATA_SILENT);
_exit(ret);
}
/* If the child was forked off successfully it will do all the cleanups, so forget about the handle
* here. */
- handle = NULL;
+ pamh = NULL;
/* Unblock SIGTERM again in the parent */
assert_se(sigprocmask(SIG_SETMASK, &old_ss, NULL) >= 0);
fail:
if (pam_code != PAM_SUCCESS) {
- pam_syslog_pam_error(handle, LOG_ERR, pam_code, "PAM failed: @PAMERR@");
+ pam_syslog_pam_error(pamh, LOG_ERR, pam_code, "PAM failed: @PAMERR@");
r = -EPERM; /* PAM errors do not map to errno */
} else
log_error_errno(r, "PAM failed: %m");
- if (handle) {
+ if (pamh) {
if (close_session)
- pam_code = pam_close_session_and_delete_credentials(handle, flags);
+ pam_code = pam_close_session_and_delete_credentials(pamh, flags);
- (void) sym_pam_end(handle, pam_code | flags);
+ (void) sym_pam_end(pamh, pam_code | flags);
}
closelog();
} AcquireHomeFlags;
static int parse_argv(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int argc, const char **argv,
AcquireHomeFlags *flags,
bool *debug) {
k = parse_boolean(v);
if (k < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
else if (flags)
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, k);
int k;
k = parse_boolean(v);
if (k < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
else if (debug)
*debug = k;
} else
- pam_syslog(handle, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
+ pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
}
return 0;
}
-static int parse_env(
- pam_handle_t *handle,
- AcquireHomeFlags *flags) {
-
+static int parse_env(pam_handle_t *pamh, AcquireHomeFlags *flags) {
const char *v;
int r;
* easy to declare the features of a display manager in code rather than configuration, and this is
* really a feature of code */
- v = pam_getenv(handle, "SYSTEMD_HOME_SUSPEND");
+ v = pam_getenv(pamh, "SYSTEMD_HOME_SUSPEND");
if (!v) {
/* Also check the process env block, so that people can control this via an env var from the
* outside of our process. */
r = parse_boolean(v);
if (r < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
else if (flags)
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, r);
}
static int acquire_user_record(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
const char *username,
bool debug,
UserRecord **ret_record,
int r;
- assert(handle);
+ assert(pamh);
if (!username) {
- r = pam_get_user(handle, &username, NULL);
+ r = pam_get_user(pamh, &username, NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get user name: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
if (isempty(username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
}
/* Possibly split out the area name */
if (carea && (filename_is_valid(carea + 1) || isempty(carea + 1))) {
username_without_area = strndup(username, carea - username);
if (!username_without_area)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
username = username_without_area;
area = strdup(carea + 1);
if (!area)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
}
/* Let's bypass all IPC complexity for the two user names we know for sure we don't manage, and for
* caching separate. */
_cleanup_free_ char *homed_field = strjoin("systemd-home-user-record-", username);
if (!homed_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
/* Let's use the cache, so that we can share it between the session and the authentication hooks */
- r = pam_get_data(handle, homed_field, (const void**) &json);
+ r = pam_get_data(pamh, homed_field, (const void**) &json);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
if (r == PAM_SUCCESS && json) {
/* We determined earlier that this is not a homed user? Then exit early. (We use -1 as
* negative cache indicator) */
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- r = pam_acquire_bus_connection(handle, "pam-systemd-home", debug, &bus, bus_data);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd-home", debug, &bus, bus_data);
if (r != PAM_SUCCESS)
return r;
r = bus_call_method(bus, bus_home_mgr, "GetUserRecordByName", &error, &reply, "s", username);
if (r < 0) {
if (bus_error_is_unknown_service(&error)) {
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"systemd-homed is not available: %s",
bus_error_message(&error, r));
goto user_unknown;
}
if (sd_bus_error_has_name(&error, BUS_ERROR_NO_SUCH_HOME)) {
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Not a user managed by systemd-homed: %s",
bus_error_message(&error, r));
goto user_unknown;
}
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
"Failed to query user record: %s", bus_error_message(&error, r));
}
r = sd_bus_message_read(reply, "sbo", &json, NULL, NULL);
if (r < 0)
- return pam_bus_log_parse_error(handle, r);
+ return pam_bus_log_parse_error(pamh, r);
fresh_data = true;
}
r = sd_json_parse(json, /* flags= */ 0, &v, NULL, NULL);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to parse JSON user record: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to parse JSON user record: %m");
ur = user_record_new();
if (!ur)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to load user record: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to load user record: %m");
/* Safety check if cached record actually matches what we are looking for */
if (!user_record_matches_user_name(ur, username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
"Acquired user record does not match user name.");
/* Update the 'username' pointer to point to our own record now. The pam_set_item() call below is
/* We passed all checks. Let's now make sure the rest of the PAM stack continues with the primary,
* normalized name of the user record (i.e. not an alias or so). */
- r = pam_set_item(handle, PAM_USER, ur->user_name);
+ r = pam_set_item(pamh, PAM_USER, ur->user_name);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to update username PAM item to '%s': @PAMERR@", ur->user_name);
/* Everything seems to be good, let's cache this data now */
* homed */
_cleanup_free_ char *json_copy = strdup(json);
if (!json_copy)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_set_data(handle, homed_field, json_copy, pam_cleanup_free);
+ r = pam_set_data(pamh, homed_field, json_copy, pam_cleanup_free);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM user record data '%s': @PAMERR@", homed_field);
/* Take a second copy: for the generic data field, the one which we share with
* and non-homed user records. */
json_copy = strdup(json);
if (!json_copy)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
_cleanup_free_ char *generic_field = strjoin("systemd-user-record-", username);
if (!generic_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_set_data(handle, generic_field, json_copy, pam_cleanup_free);
+ r = pam_set_data(pamh, generic_field, json_copy, pam_cleanup_free);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM user record data '%s': @PAMERR@", generic_field);
TAKE_PTR(json_copy);
/* Let's store the area we parsed out of the name in an env var, so that pam_systemd later can honour it. */
if (area) {
- r = pam_misc_setenv(handle, "XDG_AREA", area, /* readonly= */ 0);
+ r = pam_misc_setenv(pamh, "XDG_AREA", area, /* readonly= */ 0);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set environment variable $XDG_AREA to '%s': @PAMERR@", area);
}
user_unknown:
/* Cache this, so that we don't check again */
- r = pam_set_data(handle, homed_field, POINTER_MAX, NULL);
+ r = pam_set_data(pamh, homed_field, POINTER_MAX, NULL);
if (r != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_ERR, r,
+ pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM user record data '%s' to invalid, ignoring: @PAMERR@",
homed_field);
return PAM_USER_UNKNOWN;
}
-static int release_user_record(pam_handle_t *handle, const char *username) {
+static int release_user_record(pam_handle_t *pamh, const char *username) {
_cleanup_free_ char *homed_field = NULL, *generic_field = NULL;
int r, k;
- assert(handle);
+ assert(pamh);
assert(username);
homed_field = strjoin("systemd-home-user-record-", username);
if (!homed_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_set_data(handle, homed_field, NULL, NULL);
+ r = pam_set_data(pamh, homed_field, NULL, NULL);
if (r != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_ERR, r,
+ pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to release PAM user record data '%s': @PAMERR@", homed_field);
generic_field = strjoin("systemd-user-record-", username);
if (!generic_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- k = pam_set_data(handle, generic_field, NULL, NULL);
+ k = pam_set_data(pamh, generic_field, NULL, NULL);
if (k != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_ERR, k,
+ pam_syslog_pam_error(pamh, LOG_ERR, k,
"Failed to release PAM user record data '%s': @PAMERR@", generic_field);
return IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA) ? k : r;
}
-static void cleanup_home_fd(pam_handle_t *handle, void *data, int error_status) {
+static void cleanup_home_fd(pam_handle_t *pamh, void *data, int error_status) {
safe_close(PTR_TO_FD(data));
}
static int handle_generic_user_record_error(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
const char *user_name,
UserRecord *secret,
int ret,
/* Logs about all errors, except for PAM_CONV_ERR, i.e. when requesting more info failed. */
if (sd_bus_error_has_name(error, BUS_ERROR_HOME_ABSENT)) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL,
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL,
_("Home of user %s is currently absent, please plug in the necessary storage device or backing file system."), user_name);
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_PERM_DENIED,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_PERM_DENIED,
"Failed to acquire home for user %s: %s", user_name, bus_error_message(error, ret));
} else if (sd_bus_error_has_name(error, BUS_ERROR_AUTHENTICATION_LIMIT_HIT)) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Too frequent login attempts for user %s, try again later."), user_name);
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_MAXTRIES,
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Too frequent login attempts for user %s, try again later."), user_name);
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_MAXTRIES,
"Failed to acquire home for user %s: %s", user_name, bus_error_message(error, ret));
} else if (sd_bus_error_has_name(error, BUS_ERROR_BAD_PASSWORD)) {
/* This didn't work? Ask for an (additional?) password */
if (strv_isempty(secret->password))
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Password: "));
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Password: "));
else {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password incorrect or not sufficient for authentication of user %s."), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, try again: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password incorrect or not sufficient for authentication of user %s."), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, try again: "));
}
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "Password request aborted.");
+ pam_debug_syslog(pamh, debug, "Password request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_password(secret, STRV_MAKE(newp), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store password: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store password: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_BAD_RECOVERY_KEY)) {
_cleanup_(erase_and_freep) char *newp = NULL;
/* Hmm, homed asks for recovery key (because no regular password is defined maybe)? Provide it. */
if (strv_isempty(secret->password))
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Recovery key: "));
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Recovery key: "));
else {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password/recovery key incorrect or not sufficient for authentication of user %s."), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, reenter recovery key: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password/recovery key incorrect or not sufficient for authentication of user %s."), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, reenter recovery key: "));
}
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "Recovery key request aborted.");
+ pam_debug_syslog(pamh, debug, "Recovery key request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_password(secret, STRV_MAKE(newp), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store recovery key: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store recovery key: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_BAD_PASSWORD_AND_NO_TOKEN)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
if (strv_isempty(secret->password)) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Security token of user %s not inserted."), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Try again with password: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Security token of user %s not inserted."), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Try again with password: "));
} else {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password incorrect or not sufficient, and configured security token of user %s not inserted."), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Try again with password: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password incorrect or not sufficient, and configured security token of user %s not inserted."), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Try again with password: "));
}
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "Password request aborted.");
+ pam_debug_syslog(pamh, debug, "Password request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_password(secret, STRV_MAKE(newp), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store password: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store password: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_NEEDED)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Security token PIN: "));
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Security token PIN: "));
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "PIN request aborted.");
+ pam_debug_syslog(pamh, debug, "PIN request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store PIN: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store PIN: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PROTECTED_AUTHENTICATION_PATH_NEEDED)) {
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Please authenticate physically on security token of user %s."), user_name);
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Please authenticate physically on security token of user %s."), user_name);
r = user_record_set_pkcs11_protected_authentication_path_permitted(secret, true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r,
+ return pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set PKCS#11 protected authentication path permitted flag: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_PRESENCE_NEEDED)) {
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Please confirm presence on security token of user %s."), user_name);
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Please confirm presence on security token of user %s."), user_name);
r = user_record_set_fido2_user_presence_permitted(secret, true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r,
+ return pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set FIDO2 user presence permitted flag: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_USER_VERIFICATION_NEEDED)) {
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Please verify user on security token of user %s."), user_name);
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Please verify user on security token of user %s."), user_name);
r = user_record_set_fido2_user_verification_permitted(secret, true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r,
+ return pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set FIDO2 user verification permitted flag: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_PIN_LOCKED)) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)"));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Security token PIN is locked, please unlock it first. (Hint: Removal and re-insertion might suffice.)"));
return PAM_SERVICE_ERR;
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN)) {
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Security token PIN incorrect for user %s."), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Security token PIN incorrect for user %s."), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "PIN request aborted.");
+ pam_debug_syslog(pamh, debug, "PIN request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store PIN: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store PIN: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN_FEW_TRIES_LEFT)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Security token PIN of user %s incorrect (only a few tries left!)"), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Security token PIN of user %s incorrect (only a few tries left!)"), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "PIN request aborted.");
+ pam_debug_syslog(pamh, debug, "PIN request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store PIN: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store PIN: %m");
} else if (sd_bus_error_has_name(error, BUS_ERROR_TOKEN_BAD_PIN_ONE_TRY_LEFT)) {
_cleanup_(erase_and_freep) char *newp = NULL;
assert(secret);
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Security token PIN of user %s incorrect (only one try left!)"), user_name);
- r = pam_prompt_graceful(handle, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Security token PIN of user %s incorrect (only one try left!)"), user_name);
+ r = pam_prompt_graceful(pamh, PAM_PROMPT_ECHO_OFF, &newp, _("Sorry, retry security token PIN: "));
if (r != PAM_SUCCESS)
return PAM_CONV_ERR; /* no logging here */
if (isempty(newp)) {
- pam_debug_syslog(handle, debug, "PIN request aborted.");
+ pam_debug_syslog(pamh, debug, "PIN request aborted.");
return PAM_AUTHTOK_ERR;
}
r = user_record_set_token_pin(secret, STRV_MAKE(newp), false);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store PIN: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store PIN: %m");
} else
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
"Failed to acquire home for user %s: %s", user_name, bus_error_message(error, ret));
return PAM_SUCCESS;
}
static int acquire_home(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
AcquireHomeFlags flags,
bool debug,
PamBusData **bus_data) {
unsigned n_attempts = 0;
int r;
- assert(handle);
+ assert(pamh);
/* This acquires a reference to a home directory in the following ways:
*
* prompt the user for the missing unlock credentials, and then chainload the real shell.
*/
- r = pam_get_user(handle, &username, NULL);
+ r = pam_get_user(pamh, &username, NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get user name: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
if (isempty(username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
/* If we already have acquired the fd, let's shortcut this */
fd_field = strjoin("systemd-home-fd-", username);
if (!fd_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_get_data(handle, fd_field, &home_fd_ptr);
+ r = pam_get_data(pamh, fd_field, &home_fd_ptr);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to retrieve PAM home reference fd: @PAMERR@");
if (r == PAM_SUCCESS && PTR_TO_FD(home_fd_ptr) >= 0)
return PAM_SUCCESS;
- r = acquire_user_record(handle, username, debug, &ur, bus_data);
+ r = acquire_user_record(pamh, username, debug, &ur, bus_data);
if (r != PAM_SUCCESS)
return r;
* request to collect one more password and pass the new and all previously used passwords again. */
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- r = pam_acquire_bus_connection(handle, "pam-systemd-home", debug, &bus, bus_data);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd-home", debug, &bus, bus_data);
if (r != PAM_SUCCESS)
return r;
secret = user_record_new();
if (!secret)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
/* If there's already a cached password, use it. But if not let's authenticate
* without anything, maybe some other authentication mechanism systemd-homed
* implements (such as PKCS#11) allows us to authenticate without anything else. */
- r = pam_get_item(handle, PAM_AUTHTOK, (const void**) &cached_password);
+ r = pam_get_item(pamh, PAM_AUTHTOK, (const void**) &cached_password);
if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS))
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to get cached password: @PAMERR@");
if (!isempty(cached_password)) {
r = user_record_set_password(secret, STRV_MAKE(cached_password), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store password: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store password: %m");
}
}
r = bus_message_new_method_call(bus, &m, bus_home_mgr, method);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_message_append(m, "s", ur->user_name);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
if (do_auth) {
r = bus_message_append_secret(m, secret);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
}
r = sd_bus_message_append(m, "b", FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND));
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply);
if (r < 0) {
home_locked = true; /* Similar */
do_auth = true;
} else {
- r = handle_generic_user_record_error(handle, ur->user_name, secret, r, &error, debug);
+ r = handle_generic_user_record_error(pamh, ur->user_name, secret, r, &error, debug);
if (r == PAM_CONV_ERR) {
/* Password/PIN prompts will fail in certain environments, for example when
* we are called from OpenSSH's account or session hooks, or in systemd's
if (!FLAGS_SET(flags, ACQUIRE_REF_ANYWAY)) {
if (home_not_active)
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Home of user %s is currently not active, please log in locally first."), ur->user_name);
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Home of user %s is currently not active, please log in locally first."), ur->user_name);
if (home_locked)
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Home of user %s is currently locked, please unlock locally first."), ur->user_name);
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Home of user %s is currently locked, please unlock locally first."), ur->user_name);
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE))
- pam_syslog(handle, LOG_ERR, "Failed to prompt for password/prompt.");
+ pam_syslog(pamh, LOG_ERR, "Failed to prompt for password/prompt.");
else if (debug)
- pam_debug_syslog(handle, debug, "Failed to prompt for password/prompt.");
+ pam_debug_syslog(pamh, debug, "Failed to prompt for password/prompt.");
return home_not_active || home_locked ? PAM_PERM_DENIED : PAM_CONV_ERR;
}
r = sd_bus_message_read(reply, "h", &fd);
if (r < 0)
- return pam_bus_log_parse_error(handle, r);
+ return pam_bus_log_parse_error(pamh, r);
acquired_fd = fcntl(fd, F_DUPFD_CLOEXEC, 3);
if (acquired_fd < 0)
- return pam_syslog_errno(handle, LOG_ERR, errno,
+ return pam_syslog_errno(pamh, LOG_ERR, errno,
"Failed to duplicate acquired fd: %m");
break;
}
if (++n_attempts >= 5) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL,
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL,
_("Too many unsuccessful login attempts for user %s, refusing."), ur->user_name);
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_MAXTRIES,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_MAXTRIES,
"Failed to acquire home for user %s: %s", ur->user_name, bus_error_message(&error, r));
}
}
/* Later PAM modules may need the auth token, but only during pam_authenticate. */
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE) && !strv_isempty(secret->password)) {
- r = pam_set_item(handle, PAM_AUTHTOK, *secret->password);
+ r = pam_set_item(pamh, PAM_AUTHTOK, *secret->password);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
}
- r = pam_set_data(handle, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
+ r = pam_set_data(pamh, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
TAKE_FD(acquired_fd);
if (do_auth) {
/* We likely just activated the home directory, let's flush out the user record, since a
* newer embedded user record might have been acquired from the activation. */
- r = release_user_record(handle, ur->user_name);
+ r = release_user_record(pamh, ur->user_name);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
return r;
}
* manager for us (since it would see an inaccessible home directory). Hence set an environment
* variable that pam_systemd looks for). */
if (unrestricted) {
- r = pam_putenv(handle, "XDG_SESSION_INCOMPLETE=1");
+ r = pam_putenv(pamh, "XDG_SESSION_INCOMPLETE=1");
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_WARNING, r, "Failed to set XDG_SESSION_INCOMPLETE= environment variable: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_WARNING, r, "Failed to set XDG_SESSION_INCOMPLETE= environment variable: @PAMERR@");
- pam_syslog(handle, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
+ pam_syslog(pamh, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
} else
- pam_syslog(handle, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
+ pam_syslog(pamh, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
return PAM_SUCCESS;
}
-static int release_home_fd(pam_handle_t *handle, const char *username) {
+static int release_home_fd(pam_handle_t *pamh, const char *username) {
_cleanup_free_ char *fd_field = NULL;
const void *home_fd_ptr = NULL;
int r;
- assert(handle);
+ assert(pamh);
assert(username);
fd_field = strjoin("systemd-home-fd-", username);
if (!fd_field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_get_data(handle, fd_field, &home_fd_ptr);
+ r = pam_get_data(pamh, fd_field, &home_fd_ptr);
if (r == PAM_NO_MODULE_DATA || (r == PAM_SUCCESS && PTR_TO_FD(home_fd_ptr) < 0))
return PAM_NO_MODULE_DATA;
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to retrieve PAM home reference fd: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to retrieve PAM home reference fd: @PAMERR@");
- r = pam_set_data(handle, fd_field, NULL, NULL);
+ r = pam_set_data(pamh, fd_field, NULL, NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to release PAM home reference fd: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to release PAM home reference fd: @PAMERR@");
return PAM_SUCCESS;
}
_public_ PAM_EXTERN int pam_sm_authenticate(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int sm_flags,
int argc, const char **argv) {
pam_log_setup();
- if (parse_env(handle, &flags) < 0)
+ if (parse_env(pamh, &flags) < 0)
return PAM_AUTH_ERR;
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
&flags,
&debug) < 0)
return PAM_AUTH_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd-homed: authenticating...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-homed: authenticating...");
- return acquire_home(handle, ACQUIRE_MUST_AUTHENTICATE|flags, debug, /* bus_data= */ NULL);
+ return acquire_home(pamh, ACQUIRE_MUST_AUTHENTICATE|flags, debug, /* bus_data= */ NULL);
}
_public_ PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int sm_flags, int argc, const char **argv) {
return PAM_SUCCESS;
}
-static int fallback_shell_can_work(
- pam_handle_t *handle,
- AcquireHomeFlags *flags) {
+static int fallback_shell_can_work(pam_handle_t *pamh, AcquireHomeFlags *flags) {
const char *tty = NULL, *display = NULL;
int r;
- assert(handle);
+ assert(pamh);
assert(flags);
r = pam_get_item_many(
- handle,
+ pamh,
PAM_TTY, &tty,
PAM_XDISPLAY, &display);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM items: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM items: @PAMERR@");
/* The fallback shell logic only works on TTY logins, hence only allow it if there's no X11 display
* set, and a TTY field is set that is neither "cron" (which is what crond sets, god knows why) not
}
_public_ PAM_EXTERN int pam_sm_open_session(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int sm_flags,
int argc, const char **argv) {
pam_log_setup();
- if (parse_env(handle, &flags) < 0)
+ if (parse_env(pamh, &flags) < 0)
return PAM_SESSION_ERR;
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
&flags,
&debug) < 0)
return PAM_SESSION_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd-homed: starting session...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-homed: starting session...");
- r = fallback_shell_can_work(handle, &flags);
+ r = fallback_shell_can_work(pamh, &flags);
if (r != PAM_SUCCESS)
return r;
/* Explicitly get saved PamBusData here. Otherwise, this function may succeed without setting 'd'
* even if there is an opened sd-bus connection, and it will be leaked. See issue #31375. */
- r = pam_get_bus_data(handle, "pam-systemd-home", &d);
+ r = pam_get_bus_data(pamh, "pam-systemd-home", &d);
if (r != PAM_SUCCESS)
return r;
- r = acquire_home(handle, flags, debug, &d);
+ r = acquire_home(pamh, flags, debug, &d);
if (r == PAM_USER_UNKNOWN) /* Not managed by us? Don't complain. */
return PAM_SUCCESS;
if (r != PAM_SUCCESS)
return r;
- r = pam_putenv(handle, "SYSTEMD_HOME=1");
+ r = pam_putenv(pamh, "SYSTEMD_HOME=1");
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM environment variable $SYSTEMD_HOME: @PAMERR@");
- r = pam_putenv(handle, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
+ r = pam_putenv(pamh, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM environment variable $SYSTEMD_HOME_SUSPEND: @PAMERR@");
return PAM_SUCCESS;
}
_public_ PAM_EXTERN int pam_sm_close_session(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int sm_flags,
int argc, const char **argv) {
pam_log_setup();
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
NULL,
&debug) < 0)
return PAM_SESSION_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd-homed: closing session...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-homed: closing session...");
- r = pam_get_user(handle, &username, NULL);
+ r = pam_get_user(pamh, &username, NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get user name: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
if (isempty(username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR, "User name not set.");
/* Let's explicitly drop the reference to the homed session, so that the subsequent ReleaseHome()
* call will be able to do its thing. */
- r = release_home_fd(handle, username);
+ r = release_home_fd(pamh, username);
if (r == PAM_NO_MODULE_DATA) /* Nothing to do, we never acquired an fd */
return PAM_SUCCESS;
if (r != PAM_SUCCESS)
return r;
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- r = pam_acquire_bus_connection(handle, "pam-systemd-home", debug, &bus, NULL);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd-home", debug, &bus, NULL);
if (r != PAM_SUCCESS)
return r;
r = bus_message_new_method_call(bus, &m, bus_home_mgr, "ReleaseHome");
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_message_append(m, "s", username);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
if (r < 0) {
if (!sd_bus_error_has_name(&error, BUS_ERROR_HOME_BUSY))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SESSION_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SESSION_ERR,
"Failed to release user home: %s", bus_error_message(&error, r));
- pam_syslog(handle, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
+ pam_syslog(pamh, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
}
return PAM_SUCCESS;
}
_public_ PAM_EXTERN int pam_sm_acct_mgmt(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int sm_flags,
int argc,
const char **argv) {
pam_log_setup();
- if (parse_env(handle, &flags) < 0)
+ if (parse_env(pamh, &flags) < 0)
return PAM_AUTH_ERR;
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
&flags,
&debug) < 0)
return PAM_AUTH_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd-homed: starting account management...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-homed: starting account management...");
- r = fallback_shell_can_work(handle, &flags);
+ r = fallback_shell_can_work(pamh, &flags);
if (r != PAM_SUCCESS)
return r;
- r = acquire_home(handle, flags, debug, /* bus_data= */ NULL);
+ r = acquire_home(pamh, flags, debug, /* bus_data= */ NULL);
if (r != PAM_SUCCESS)
return r;
- r = acquire_user_record(handle, /* username= */ NULL, debug, &ur, /* bus_data= */ NULL);
+ r = acquire_user_record(pamh, /* username= */ NULL, debug, &ur, /* bus_data= */ NULL);
if (r != PAM_SUCCESS)
return r;
switch (r) {
case -ESTALE:
- pam_syslog(handle, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
+ pam_syslog(pamh, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
break;
case -ENOLCK:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("User record is blocked, prohibiting access."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("User record is blocked, prohibiting access."));
return PAM_ACCT_EXPIRED;
case -EL2HLT:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("User record is not valid yet, prohibiting access."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("User record is not valid yet, prohibiting access."));
return PAM_ACCT_EXPIRED;
case -EL3HLT:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("User record is not valid anymore, prohibiting access."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("User record is not valid anymore, prohibiting access."));
return PAM_ACCT_EXPIRED;
default:
if (r < 0) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("User record not valid, prohibiting access."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("User record not valid, prohibiting access."));
return PAM_ACCT_EXPIRED;
}
}
usec_t n = now(CLOCK_REALTIME);
if (t > n) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Too many logins, try again in %s."),
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Too many logins, try again in %s."),
FORMAT_TIMESPAN(t - n, USEC_PER_SEC));
return PAM_MAXTRIES;
switch (r) {
case -EKEYREVOKED:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password change required."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password change required."));
return PAM_NEW_AUTHTOK_REQD;
case -EOWNERDEAD:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password expired, change required."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password expired, change required."));
return PAM_NEW_AUTHTOK_REQD;
/* Strictly speaking this is only about password expiration, and we might want to allow
* authentication via PKCS#11 or so, but let's ignore this fine distinction for now. */
case -EKEYREJECTED:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password is expired, but can't change, refusing login."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password is expired, but can't change, refusing login."));
return PAM_AUTHTOK_EXPIRED;
case -EKEYEXPIRED:
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("Password will expire soon, please change."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Password will expire soon, please change."));
break;
case -ESTALE:
/* If the system clock is wrong, let's log but continue */
- pam_syslog(handle, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
+ pam_syslog(pamh, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
break;
case -EROFS:
default:
if (r < 0) {
- (void) pam_prompt_graceful(handle, PAM_ERROR_MSG, NULL, _("User record not valid, prohibiting access."));
+ (void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("User record not valid, prohibiting access."));
return PAM_AUTHTOK_EXPIRED;
}
}
}
_public_ PAM_EXTERN int pam_sm_chauthtok(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int sm_flags,
int argc,
const char **argv) {
pam_log_setup();
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
NULL,
&debug) < 0)
return PAM_AUTH_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd-homed: starting authentication token management...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-homed: starting authentication token management...");
- r = acquire_user_record(handle, /* username= */ NULL, debug, &ur, /* bus_data= */ NULL);
+ r = acquire_user_record(pamh, /* username= */ NULL, debug, &ur, /* bus_data= */ NULL);
if (r != PAM_SUCCESS)
return r;
/* Start with cached credentials */
r = pam_get_item_many(
- handle,
+ pamh,
PAM_OLDAUTHTOK, &old_password,
PAM_AUTHTOK, &new_password);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get cached passwords: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get cached passwords: @PAMERR@");
if (isempty(new_password)) {
/* No, it's not cached, then let's ask for the password and its verification, and cache
* it. */
- r = pam_get_authtok_noverify(handle, &new_password, "New password: ");
+ r = pam_get_authtok_noverify(pamh, &new_password, "New password: ");
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get new password: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get new password: @PAMERR@");
if (isempty(new_password)) {
- pam_debug_syslog(handle, debug, "Password request aborted.");
+ pam_debug_syslog(pamh, debug, "Password request aborted.");
return PAM_AUTHTOK_ERR;
}
- r = pam_get_authtok_verify(handle, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
+ r = pam_get_authtok_verify(pamh, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get password again: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get password again: @PAMERR@");
// FIXME: pam_pwquality will ask for the password a third time. It really shouldn't do
// that, and instead assume the password was already verified once when it is found to be
old_secret = user_record_new();
if (!old_secret)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
if (!isempty(old_password)) {
r = user_record_set_password(old_secret, STRV_MAKE(old_password), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store old password: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store old password: %m");
}
new_secret = user_record_new();
if (!new_secret)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
r = user_record_set_password(new_secret, STRV_MAKE(new_password), true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to store new password: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to store new password: %m");
_cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
- r = pam_acquire_bus_connection(handle, "pam-systemd-home", debug, &bus, NULL);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd-home", debug, &bus, NULL);
if (r != PAM_SUCCESS)
return r;
r = bus_message_new_method_call(bus, &m, bus_home_mgr, "ChangePasswordHome");
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_message_append(m, "s", ur->user_name);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = bus_message_append_secret(m, new_secret);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = bus_message_append_secret(m, old_secret);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_call(bus, m, HOME_SLOW_BUS_CALL_TIMEOUT_USEC, &error, NULL);
if (r < 0) {
- r = handle_generic_user_record_error(handle, ur->user_name, old_secret, r, &error, debug);
+ r = handle_generic_user_record_error(pamh, ur->user_name, old_secret, r, &error, debug);
if (r == PAM_CONV_ERR)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to prompt for password/prompt.");
if (r != PAM_SUCCESS)
return r;
} else
- return pam_syslog_pam_error(handle, LOG_NOTICE, PAM_SUCCESS,
+ return pam_syslog_pam_error(pamh, LOG_NOTICE, PAM_SUCCESS,
"Successfully changed password for user %s.", ur->user_name);
if (++n_attempts >= 5)
/* Try again */
};
- return pam_syslog_pam_error(handle, LOG_NOTICE, PAM_MAXTRIES,
+ return pam_syslog_pam_error(pamh, LOG_NOTICE, PAM_MAXTRIES,
"Failed to change password for user %s: @PAMERR@", ur->user_name);
}
#define LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC (2*USEC_PER_MINUTE)
static int parse_caps(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
const char *value,
uint64_t *caps) {
bool subtract;
int r;
- assert(handle);
+ assert(pamh);
assert(value);
if (value[0] == '~') {
c = capability_from_name(s);
if (c < 0) {
- pam_syslog(handle, LOG_WARNING, "Unknown capability, ignoring: %s", s);
+ pam_syslog(pamh, LOG_WARNING, "Unknown capability, ignoring: %s", s);
continue;
}
}
static int parse_argv(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int argc, const char **argv,
const char **class,
const char **type,
int r;
- assert(handle);
+ assert(pamh);
assert(argc >= 0);
assert(argc == 0 || argv);
} else if ((p = startswith(argv[i], "area="))) {
if (!isempty(p) && !filename_is_valid(p))
- pam_syslog(handle, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
+ pam_syslog(pamh, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
else if (area)
*area = p;
} else if ((p = startswith(argv[i], "debug="))) {
r = parse_boolean(p);
if (r < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
else if (debug)
*debug = r;
} else if ((p = startswith(argv[i], "default-capability-bounding-set="))) {
- r = parse_caps(handle, p, default_capability_bounding_set);
+ r = parse_caps(pamh, p, default_capability_bounding_set);
if (r < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
} else if ((p = startswith(argv[i], "default-capability-ambient-set="))) {
- r = parse_caps(handle, p, default_capability_ambient_set);
+ r = parse_caps(pamh, p, default_capability_ambient_set);
if (r < 0)
- pam_syslog(handle, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
} else
- pam_syslog(handle, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
+ pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
}
return 0;
}
-static int acquire_user_record(
- pam_handle_t *handle,
- UserRecord **ret_record) {
-
+static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
int r;
- assert(handle);
+ assert(pamh);
const char *username = NULL;
- r = pam_get_user(handle, &username, NULL);
+ r = pam_get_user(pamh, &username, NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get user name: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
if (isempty(username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR, "User name not valid.");
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR, "User name not valid.");
/* If pam_systemd_homed (or some other module) already acquired the user record we can reuse it
* here. */
_cleanup_free_ char *field = strjoin("systemd-user-record-", username);
if (!field)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
const char *json = NULL;
- r = pam_get_data(handle, field, (const void**) &json);
+ r = pam_get_data(pamh, field, (const void**) &json);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
if (r == PAM_SUCCESS && json) {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
/* Parse cached record */
r = sd_json_parse(json, SD_JSON_PARSE_SENSITIVE, &v, NULL, NULL);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to parse JSON user record: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to parse JSON user record: %m");
ur = user_record_new();
if (!ur)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
r = user_record_load(ur, v, USER_RECORD_LOAD_REFUSE_SECRET|USER_RECORD_PERMISSIVE);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to load user record: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to load user record: %m");
/* Safety check if cached record actually matches what we are looking for */
if (!user_record_matches_user_name(ur, username))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
"Acquired user record does not match user name.");
} else {
_cleanup_free_ char *formatted = NULL;
/* Request the record ourselves */
r = userdb_by_name(username, /* match= */ NULL, /* flags= */ 0, &ur);
if (r < 0) {
- pam_syslog_errno(handle, LOG_ERR, r, "Failed to get user record: %m");
+ pam_syslog_errno(pamh, LOG_ERR, r, "Failed to get user record: %m");
return PAM_USER_UNKNOWN;
}
if (!uid_is_valid(ur->uid))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_USER_UNKNOWN,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_USER_UNKNOWN,
"User record of user '%s' has no UID, refusing.", username);
r = sd_json_variant_format(ur->json, 0, &formatted);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to format user JSON: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to format user JSON: %m");
/* And cache it for everyone else */
- r = pam_set_data(handle, field, formatted, pam_cleanup_free);
+ r = pam_set_data(pamh, field, formatted, pam_cleanup_free);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM user record data '%s': @PAMERR@", field);
TAKE_PTR(formatted);
}
if (!uid_is_valid(ur->uid))
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SERVICE_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
"Acquired user record does not have a UID.");
if (ret_record)
return 0;
}
-static int append_session_memory_max(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+static int append_session_memory_max(pam_handle_t *pamh, sd_bus_message *m, const char *limit) {
int r;
- assert(handle);
+ assert(pamh);
assert(m);
if (isempty(limit))
uint64_t val;
r = parse_size(limit, 1024, &val);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
return 0;
}
return sd_bus_message_append(m, "(sv)", "MemoryMax", "t", val);
}
-static int append_session_runtime_max_sec(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+static int append_session_runtime_max_sec(pam_handle_t *pamh, sd_bus_message *m, const char *limit) {
int r;
- assert(handle);
+ assert(pamh);
assert(m);
/* No need to parse "infinity" here, it will be set by default later in scope_init() */
usec_t val;
r = parse_sec(limit, &val);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
return 0;
}
return sd_bus_message_append(m, "(sv)", "RuntimeMaxUSec", "t", (uint64_t) val);
}
-static int append_session_tasks_max(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+static int append_session_tasks_max(pam_handle_t *pamh, sd_bus_message *m, const char *limit) {
int r;
- assert(handle);
+ assert(pamh);
assert(m);
/* No need to parse "infinity" here, it will be set unconditionally later in manager_start_scope() */
uint64_t val;
r = safe_atou64(limit, &val);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
return 0;
}
return sd_bus_message_append(m, "(sv)", "TasksMax", "t", val);
}
-static int append_session_cpu_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+static int append_session_cpu_weight(pam_handle_t *pamh, sd_bus_message *m, const char *limit) {
int r;
- assert(handle);
+ assert(pamh);
assert(m);
if (isempty(limit))
uint64_t val;
r = cg_cpu_weight_parse(limit, &val);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
return 0;
}
return sd_bus_message_append(m, "(sv)", "CPUWeight", "t", val);
}
-static int append_session_io_weight(pam_handle_t *handle, sd_bus_message *m, const char *limit) {
+static int append_session_io_weight(pam_handle_t *pamh, sd_bus_message *m, const char *limit) {
int r;
- assert(handle);
+ assert(pamh);
assert(m);
if (isempty(limit))
uint64_t val;
r = cg_weight_parse(limit, &val);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
+ pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
return 0;
}
return sd_bus_message_append(m, "(sv)", "IOWeight", "t", val);
}
-static const char* getenv_harder(pam_handle_t *handle, const char *key, const char *fallback) {
+static const char* getenv_harder(pam_handle_t *pamh, const char *key, const char *fallback) {
const char *v;
- assert(handle);
+ assert(pamh);
assert(key);
/* Looks for an environment variable, preferably in the environment block associated with the
* PAM services don't have to be reworked to set systemd-specific properties, but these properties
* can still be set from the unit file Environment= block. */
- v = pam_getenv(handle, key);
+ v = pam_getenv(pamh, key);
if (!isempty(v))
return v;
return fallback;
}
-static bool getenv_harder_bool(pam_handle_t *handle, const char *key, bool fallback) {
+static bool getenv_harder_bool(pam_handle_t *pamh, const char *key, bool fallback) {
const char *v;
int r;
- assert(handle);
+ assert(pamh);
assert(key);
- v = getenv_harder(handle, key, NULL);
+ v = getenv_harder(pamh, key, NULL);
if (isempty(v))
return fallback;
r = parse_boolean(v);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING,
+ pam_syslog(pamh, LOG_WARNING,
"Failed to parse environment variable value '%s' of '%s', falling back to using '%s'.",
v, key, true_false(fallback));
return fallback;
return r;
}
-static uint32_t getenv_harder_uint32(pam_handle_t *handle, const char *key, uint32_t fallback) {
+static uint32_t getenv_harder_uint32(pam_handle_t *pamh, const char *key, uint32_t fallback) {
int r;
- assert(handle);
+ assert(pamh);
assert(key);
- const char *v = getenv_harder(handle, key, NULL);
+ const char *v = getenv_harder(pamh, key, NULL);
if (isempty(v))
return fallback;
uint32_t u;
r = safe_atou32(v, &u);
if (r < 0) {
- pam_syslog(handle, LOG_WARNING,
+ pam_syslog(pamh, LOG_WARNING,
"Failed to parse environment variable value '%s' of '%s' as unsigned integer, falling back to using %" PRIu32 ".",
v, key, fallback);
return fallback;
return u;
}
-static int update_environment(pam_handle_t *handle, const char *key, const char *value) {
+static int update_environment(pam_handle_t *pamh, const char *key, const char *value) {
int r;
- assert(handle);
+ assert(pamh);
assert(key);
/* Updates the environment, and removes environment variables if value is NULL or empty. Also, log
* call it without the variable actually being set. Hence we check explicitly if it's set
* before. */
- if (!pam_getenv(handle, key))
+ if (!pam_getenv(pamh, key))
return PAM_SUCCESS;
- r = pam_putenv(handle, key);
+ r = pam_putenv(pamh, key);
if (!IN_SET(r, PAM_SUCCESS, PAM_BAD_ITEM))
- return pam_syslog_pam_error(handle, LOG_WARNING, r,
+ return pam_syslog_pam_error(pamh, LOG_WARNING, r,
"Failed to unset %s environment variable: @PAMERR@", key);
return PAM_SUCCESS;
}
- r = pam_misc_setenv(handle, key, value, /* readonly= */ false);
+ r = pam_misc_setenv(pamh, key, value, /* readonly= */ false);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set environment variable %s: @PAMERR@", key);
return PAM_SUCCESS;
}
-static int propagate_credential_to_environment(pam_handle_t *handle, bool debug, const char *credential, const char *varname) {
+static int propagate_credential_to_environment(pam_handle_t *pamh, bool debug, const char *credential, const char *varname) {
int r;
- assert(handle);
+ assert(pamh);
assert(credential);
assert(varname);
r = read_credential(credential, (void**) &value, /* ret_size= */ NULL);
if (r < 0) {
- pam_debug_syslog_errno(handle, debug, r, "Failed to read credential '%s', ignoring: %m", credential);
+ pam_debug_syslog_errno(pamh, debug, r, "Failed to read credential '%s', ignoring: %m", credential);
return PAM_SUCCESS;
}
- r = pam_misc_setenv(handle, varname, value, 0);
+ r = pam_misc_setenv(pamh, varname, value, 0);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set environment variable %s: @PAMERR@", varname);
return PAM_SUCCESS;
}
-static bool validate_runtime_directory(pam_handle_t *handle, const char *path, uid_t uid) {
+static bool validate_runtime_directory(pam_handle_t *pamh, const char *path, uid_t uid) {
struct stat st;
- assert(handle);
+ assert(pamh);
assert(path);
/* Some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
if (!path_is_absolute(path)) {
- pam_syslog(handle, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
+ pam_syslog(pamh, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
goto fail;
}
if (lstat(path, &st) < 0) {
- pam_syslog_errno(handle, LOG_ERR, errno, "Failed to stat() runtime directory '%s': %m", path);
+ pam_syslog_errno(pamh, LOG_ERR, errno, "Failed to stat() runtime directory '%s': %m", path);
goto fail;
}
if (!S_ISDIR(st.st_mode)) {
- pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
+ pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
goto fail;
}
if (st.st_uid != uid) {
- pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
+ pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
goto fail;
}
return true;
fail:
- pam_syslog(handle, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
+ pam_syslog(pamh, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
return false;
}
-static int pam_putenv_and_log(pam_handle_t *handle, const char *e, bool debug) {
+static int pam_putenv_and_log(pam_handle_t *pamh, const char *e, bool debug) {
int r;
- assert(handle);
+ assert(pamh);
assert(e);
- r = pam_putenv(handle, e);
+ r = pam_putenv(pamh, e);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM environment variable %s: @PAMERR@", e);
- pam_debug_syslog(handle, debug, "PAM environment variable %s set based on user record.", e);
+ pam_debug_syslog(pamh, debug, "PAM environment variable %s set based on user record.", e);
return PAM_SUCCESS;
}
static int apply_user_record_settings(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
UserRecord *ur,
bool debug,
uint64_t default_capability_bounding_set,
_cleanup_strv_free_ char **langs = NULL;
int r;
- assert(handle);
+ assert(pamh);
assert(ur);
if (ur->umask != MODE_INVALID) {
umask(ur->umask);
- pam_debug_syslog(handle, debug, "Set user umask to %04o based on user record.", ur->umask);
+ pam_debug_syslog(pamh, debug, "Set user umask to %04o based on user record.", ur->umask);
}
STRV_FOREACH(i, ur->environment) {
- r = pam_putenv_and_log(handle, *i, debug);
+ r = pam_putenv_and_log(pamh, *i, debug);
if (r != PAM_SUCCESS)
return r;
}
joined = strjoin("EMAIL=", ur->email_address);
if (!joined)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_putenv_and_log(handle, joined, debug);
+ r = pam_putenv_and_log(pamh, joined, debug);
if (r != PAM_SUCCESS)
return r;
}
if (ur->time_zone) {
if (!timezone_is_valid(ur->time_zone, LOG_DEBUG))
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Time zone specified in user record is not valid locally, not setting $TZ.");
else {
_cleanup_free_ char *joined = NULL;
joined = strjoin("TZ=:", ur->time_zone);
if (!joined)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_putenv_and_log(handle, joined, debug);
+ r = pam_putenv_and_log(pamh, joined, debug);
if (r != PAM_SUCCESS)
return r;
}
r = user_record_languages(ur, &langs);
if (r < 0)
- pam_syslog_errno(handle, LOG_ERR, r,
+ pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to acquire user's language preferences, ignoring: %m");
else if (strv_isempty(langs))
; /* User has no preference set so we do nothing */
else if (locale_is_installed(langs[0]) <= 0)
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Preferred languages specified in user record are not installed locally, not setting $LANG or $LANGUAGE.");
else {
_cleanup_free_ char *lang = NULL;
lang = strjoin("LANG=", langs[0]);
if (!lang)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_putenv_and_log(handle, lang, debug);
+ r = pam_putenv_and_log(pamh, lang, debug);
if (r != PAM_SUCCESS)
return r;
joined = strv_join(langs, ":");
if (!joined)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
language = strjoin("LANGUAGE=", joined);
if (!language)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_putenv_and_log(handle, language, debug);
+ r = pam_putenv_and_log(pamh, language, debug);
if (r != PAM_SUCCESS)
return r;
}
if (nice_is_valid(ur->nice_level)) {
if (nice(ur->nice_level) < 0)
- pam_syslog_errno(handle, LOG_WARNING, errno,
+ pam_syslog_errno(pamh, LOG_WARNING, errno,
"Failed to set nice level to %i, ignoring: %m", ur->nice_level);
else
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Nice level set to %i, based on user record.", ur->nice_level);
}
r = setrlimit_closest(rl, ur->rlimits[rl]);
if (r < 0)
- pam_syslog_errno(handle, LOG_ERR, r,
+ pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set resource limit %s, ignoring: %m", rlimit_to_string(rl));
else
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Resource limit %s set, based on user record.", rlimit_to_string(rl));
}
r = capability_ambient_set_apply(a, /* also_inherit= */ true);
if (r < 0)
- pam_syslog_errno(handle, LOG_ERR, r,
+ pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set ambient capabilities, ignoring: %m");
}
if (b != CAP_MASK_UNSET && !cap_test_all(b)) {
r = capability_bounding_set_drop(b, /* right_now= */ false);
if (r < 0)
- pam_syslog_errno(handle, LOG_ERR, r,
+ pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to set bounding capabilities, ignoring: %m");
}
static int create_session_message(
sd_bus *bus,
- pam_handle_t *handle,
+ pam_handle_t *pamh,
UserRecord *ur,
const SessionContext *context,
bool avoid_pidfd,
int r;
assert(bus);
- assert(handle);
+ assert(pamh);
assert(ur);
assert(context);
assert(ret);
if (r < 0)
return r;
- r = append_session_memory_max(handle, m, context->memory_max);
+ r = append_session_memory_max(pamh, m, context->memory_max);
if (r < 0)
return r;
- r = append_session_runtime_max_sec(handle, m, context->runtime_max_sec);
+ r = append_session_runtime_max_sec(pamh, m, context->runtime_max_sec);
if (r < 0)
return r;
- r = append_session_tasks_max(handle, m, context->tasks_max);
+ r = append_session_tasks_max(pamh, m, context->tasks_max);
if (r < 0)
return r;
- r = append_session_cpu_weight(handle, m, context->cpu_weight);
+ r = append_session_cpu_weight(pamh, m, context->cpu_weight);
if (r < 0)
return r;
- r = append_session_io_weight(handle, m, context->io_weight);
+ r = append_session_io_weight(pamh, m, context->io_weight);
if (r < 0)
return r;
}
static void session_context_mangle(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
SessionContext *c,
UserRecord *ur,
bool debug) {
- assert(handle);
+ assert(pamh);
assert(c);
assert(ur);
}
if (c->seat && !streq(c->seat, "seat0") && c->vtnr != 0) {
- pam_debug_syslog(handle, debug, "Ignoring vtnr %"PRIu32" for %s which is not seat0.", c->vtnr, c->seat);
+ pam_debug_syslog(pamh, debug, "Ignoring vtnr %"PRIu32" for %s which is not seat0.", c->vtnr, c->seat);
c->vtnr = 0;
}
if (isempty(c->type)) {
c->type = !isempty(c->display) ? "x11" :
!isempty(c->tty) ? "tty" : "unspecified";
- pam_debug_syslog(handle, debug, "Automatically chose session type '%s'.", c->type);
+ pam_debug_syslog(pamh, debug, "Automatically chose session type '%s'.", c->type);
}
if (!c->area)
c->area = ur->default_area;
if (!isempty(c->area) && !filename_is_valid(c->area)) {
- pam_syslog(handle, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
+ pam_syslog(pamh, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
c->area = NULL;
}
;
}
- pam_debug_syslog(handle, debug, "Automatically chose session class '%s'.", c->class);
+ pam_debug_syslog(pamh, debug, "Automatically chose session class '%s'.", c->class);
}
if (c->incomplete) {
if (streq(c->class, "user"))
c->class = "user-incomplete";
else
- pam_syslog(handle, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
+ pam_syslog(pamh, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
}
c->remote = !isempty(c->remote_host) && !is_localhost(c->remote_host);
}
static int register_session(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
SessionContext *c,
UserRecord *ur,
bool debug,
int r;
- assert(handle);
+ assert(pamh);
assert(c);
assert(ur);
assert(ret_seat);
/* We don't register session class none with logind */
if (streq(c->class, "none")) {
- pam_debug_syslog(handle, debug, "Skipping logind registration for session class none.");
+ pam_debug_syslog(pamh, debug, "Skipping logind registration for session class none.");
*ret_seat = *ret_type = *ret_runtime_dir = NULL;
return PAM_SUCCESS;
}
/* Make most of this a NOP on non-logind systems */
if (!logind_running()) {
- pam_debug_syslog(handle, debug, "Skipping logind registration as logind is not running.");
+ pam_debug_syslog(pamh, debug, "Skipping logind registration as logind is not running.");
*ret_seat = *ret_type = *ret_runtime_dir = NULL;
return PAM_SUCCESS;
}
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Asking logind to create session: "
"uid="UID_FMT" pid="PID_FMT" service=%s type=%s class=%s desktop=%s seat=%s vtnr=%"PRIu32" tty=%s display=%s remote=%s remote_user=%s remote_host=%s",
ur->uid, getpid_cached(),
c->type, c->class, strempty(c->desktop),
strempty(c->seat), c->vtnr, strempty(c->tty), strempty(c->display),
yes_no(c->remote), strempty(c->remote_user), strempty(c->remote_host));
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Session limits: "
"memory_max=%s tasks_max=%s cpu_weight=%s io_weight=%s runtime_max_sec=%s",
strna(c->memory_max), strna(c->tasks_max), strna(c->cpu_weight), strna(c->io_weight), strna(c->runtime_max_sec));
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.Login");
if (r < 0)
- pam_debug_syslog_errno(handle, debug, r, "Failed to connect to logind via Varlink, falling back to D-Bus: %m");
+ pam_debug_syslog_errno(pamh, debug, r, "Failed to connect to logind via Varlink, falling back to D-Bus: %m");
else {
r = sd_varlink_set_allow_fd_passing_output(vl, true);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to enable output fd passing on Varlink socket: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to enable output fd passing on Varlink socket: %m");
r = sd_varlink_set_relative_timeout(vl, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to set relative timeout on Varlink socket: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to set relative timeout on Varlink socket: %m");
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
r = pidref_set_self(&pidref);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to acquire PID reference on ourselves: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to acquire PID reference on ourselves: %m");
sd_json_variant *vreply = NULL;
const char *error_id = NULL;
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteUser", c->remote_user),
JSON_BUILD_PAIR_STRING_NON_EMPTY("RemoteHost", c->remote_host));
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r,
+ return pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to issue io.systemd.Login.CreateSession varlink call: %m");
if (streq_ptr(error_id, "io.systemd.Login.AlreadySessionMember")) {
/* We are already in a session, don't do anything */
- pam_debug_syslog(handle, debug, "Not creating session: %s", error_id);
+ pam_debug_syslog(pamh, debug, "Not creating session: %s", error_id);
*ret_seat = *ret_type= *ret_runtime_dir = NULL;
return PAM_SUCCESS;
}
if (error_id)
- return pam_syslog_errno(handle, LOG_ERR, sd_varlink_error_to_errno(error_id, vreply),
+ return pam_syslog_errno(pamh, LOG_ERR, sd_varlink_error_to_errno(error_id, vreply),
"Varlink call io.systemd.Login.CreateSession failed: %s", error_id);
struct {
r = sd_json_dispatch(vreply, dispatch_table, SD_JSON_ALLOW_EXTENSIONS, &p);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to parse CreateSession() reply: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to parse CreateSession() reply: %m");
id = p.id;
runtime_path = p.runtime_path;
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
/* Talk to logind over the message bus */
- r = pam_acquire_bus_connection(handle, "pam-systemd", debug, &bus, &d);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd", debug, &bus, &d);
if (r != PAM_SUCCESS)
return r;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
r = create_session_message(
bus,
- handle,
+ pamh,
ur,
c,
/* avoid_pidfd= */ false,
&m);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply);
if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) {
sd_bus_error_free(&error);
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"CreateSessionWithPIDFD() API is not available, retrying with CreateSession().");
m = sd_bus_message_unref(m);
r = create_session_message(bus,
- handle,
+ pamh,
ur,
c,
/* avoid_pidfd= */ true,
&m);
if (r < 0)
- return pam_bus_log_create_error(handle, r);
+ return pam_bus_log_create_error(pamh, r);
r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply);
}
if (r < 0) {
if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) {
/* We are already in a session, don't do anything */
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Not creating session: %s", bus_error_message(&error, r));
*ret_seat = *ret_type = *ret_runtime_dir = NULL;
return PAM_SUCCESS;
}
- pam_syslog(handle, LOG_ERR,
+ pam_syslog(pamh, LOG_ERR,
"Failed to create session: %s", bus_error_message(&error, r));
return PAM_SESSION_ERR;
}
&real_vtnr,
&existing);
if (r < 0)
- return pam_bus_log_parse_error(handle, r);
+ return pam_bus_log_parse_error(pamh, r);
}
- pam_debug_syslog(handle, debug,
+ pam_debug_syslog(pamh, debug,
"Reply from logind: "
"id=%s object_path=%s runtime_path=%s seat=%s vtnr=%u original_uid=%u",
id, strna(object_path), runtime_path, real_seat, real_vtnr, original_uid);
/* Please update manager_default_environment() in core/manager.c accordingly if more session envvars
* shall be added. */
- r = update_environment(handle, "XDG_SESSION_ID", id);
+ r = update_environment(pamh, "XDG_SESSION_ID", id);
if (r != PAM_SUCCESS)
return r;
_cleanup_free_ char *real_type = strdup(c->type); /* make copy because this might point to env block, which we are going to update shortly */
if (!real_type)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = update_environment(handle, "XDG_SESSION_TYPE", c->type);
+ r = update_environment(pamh, "XDG_SESSION_TYPE", c->type);
if (r != PAM_SUCCESS)
return r;
- r = update_environment(handle, "XDG_SESSION_CLASS", c->class);
+ r = update_environment(pamh, "XDG_SESSION_CLASS", c->class);
if (r != PAM_SUCCESS)
return r;
- r = update_environment(handle, "XDG_SESSION_DESKTOP", c->desktop);
+ r = update_environment(pamh, "XDG_SESSION_DESKTOP", c->desktop);
if (r != PAM_SUCCESS)
return r;
- r = update_environment(handle, "XDG_SEAT", real_seat);
+ r = update_environment(pamh, "XDG_SEAT", real_seat);
if (r != PAM_SUCCESS)
return r;
char buf[DECIMAL_STR_MAX(real_vtnr)];
xsprintf(buf, "%u", real_vtnr);
- r = update_environment(handle, "XDG_VTNR", buf);
+ r = update_environment(pamh, "XDG_VTNR", buf);
if (r != PAM_SUCCESS)
return r;
}
- r = pam_set_data(handle, "systemd.existing", INT_TO_PTR(!!existing), NULL);
+ r = pam_set_data(pamh, "systemd.existing", INT_TO_PTR(!!existing), NULL);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to install existing flag: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to install existing flag: @PAMERR@");
/* Don't set $XDG_RUNTIME_DIR if the user we now authenticated for does not match the
* original user of the session. We do this in order not to result in privileged apps
* clobbering the runtime directory unnecessarily. */
_cleanup_free_ char *rt = NULL;
- if (original_uid == ur->uid && validate_runtime_directory(handle, runtime_path, ur->uid))
+ if (original_uid == ur->uid && validate_runtime_directory(pamh, runtime_path, ur->uid))
if (strdup_to(&rt, runtime_path) < 0)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
/* Everything worked, hence let's patch in the data we learned. Since 'real_set' points into the
* D-Bus message, let's copy it and return it as a buffer */
_cleanup_free_ char *rs = NULL;
if (strdup_to(&rs, real_seat) < 0)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
c->vtnr = real_vtnr;
c->seat = *ret_seat = TAKE_PTR(rs);
return PAM_SUCCESS;
}
-static int import_shell_credentials(pam_handle_t *handle, bool debug) {
+static int import_shell_credentials(pam_handle_t *pamh, bool debug) {
static const char *const propagate[] = {
"shell.prompt.prefix", "SHELL_PROMPT_PREFIX",
};
int r;
- assert(handle);
+ assert(pamh);
STRV_FOREACH_PAIR(k, v, propagate) {
- r = propagate_credential_to_environment(handle, debug, *k, *v);
+ r = propagate_credential_to_environment(pamh, debug, *k, *v);
if (r != PAM_SUCCESS)
return r;
}
}
static int make_area_runtime_directory(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
UserRecord *ur,
const char *runtime_directory,
const char *area,
char **ret) {
- assert(handle);
+ assert(pamh);
assert(ur);
assert(runtime_directory);
assert(area);
_cleanup_close_ int fd = open(runtime_directory, O_CLOEXEC|O_PATH|O_DIRECTORY);
if (fd < 0)
- return pam_syslog_errno(handle, LOG_ERR, errno, "Unable to open runtime directory '%s': %m", runtime_directory);
+ return pam_syslog_errno(pamh, LOG_ERR, errno, "Unable to open runtime directory '%s': %m", runtime_directory);
_cleanup_close_ int fd_areas = mkdir_chown_open_directory(fd, "Areas", ur->uid, user_record_gid(ur), 0755);
if (fd_areas < 0)
- return pam_syslog_errno(handle, LOG_ERR, fd_areas, "Unable to create 'Areas' directory below '%s': %m", runtime_directory);
+ return pam_syslog_errno(pamh, LOG_ERR, fd_areas, "Unable to create 'Areas' directory below '%s': %m", runtime_directory);
_cleanup_close_ int fd_area = mkdir_chown_open_directory(fd_areas, area, ur->uid, user_record_gid(ur), 0755);
if (fd_area < 0)
- return pam_syslog_errno(handle, LOG_ERR, fd_area, "Unable to create '%s' directory below '%s/Areas': %m", area, runtime_directory);
+ return pam_syslog_errno(pamh, LOG_ERR, fd_area, "Unable to create '%s' directory below '%s/Areas': %m", area, runtime_directory);
char *j = path_join(runtime_directory, "Areas", area);
if (!j)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
*ret = j;
return 0;
}
-static int export_legacy_dbus_address(
- pam_handle_t *handle,
- const char *runtime) {
+static int export_legacy_dbus_address(pam_handle_t *pamh, const char *runtime) {
- assert(handle);
+ assert(pamh);
assert(runtime);
/* We need to export $DBUS_SESSION_BUS_ADDRESS because various applications will not connect
const char *s = strjoina(runtime, "/bus");
if (access(s, F_OK) < 0) {
if (errno != ENOENT)
- pam_syslog_errno(handle, LOG_WARNING, errno, "Failed to check if %s/bus exists, ignoring: %m", runtime);
+ pam_syslog_errno(pamh, LOG_WARNING, errno, "Failed to check if %s/bus exists, ignoring: %m", runtime);
return PAM_SUCCESS;
}
_cleanup_free_ char *t = NULL;
if (asprintf(&t, DEFAULT_USER_BUS_ADDRESS_FMT, runtime) < 0)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- return update_environment(handle, "DBUS_SESSION_BUS_ADDRESS", t);
+ return update_environment(pamh, "DBUS_SESSION_BUS_ADDRESS", t);
}
static int setup_runtime_directory(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
UserRecord *ur,
const char *runtime_directory,
const char *area) {
int r;
- assert(handle);
+ assert(pamh);
assert(ur);
if (!runtime_directory) {
/* If this is an area switch request, always reset $XDG_RUNTIME_DIR if we got nothing
* to ensure the main runtime dir won't be clobbered. */
if (area)
- return update_environment(handle, "XDG_RUNTIME_DIR", NULL);
+ return update_environment(pamh, "XDG_RUNTIME_DIR", NULL);
return PAM_SUCCESS;
}
* clean-up of the whole $XDG_RUNTIME_DIR hierarchy when the user finally logs out. */
_cleanup_free_ char *per_area_runtime_directory = NULL;
if (area) {
- r = make_area_runtime_directory(handle, ur, runtime_directory, area, &per_area_runtime_directory);
+ r = make_area_runtime_directory(pamh, ur, runtime_directory, area, &per_area_runtime_directory);
if (r != PAM_SUCCESS)
return r;
runtime_directory = per_area_runtime_directory;
}
- r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_directory);
+ r = update_environment(pamh, "XDG_RUNTIME_DIR", runtime_directory);
if (r != PAM_SUCCESS)
return r;
- return export_legacy_dbus_address(handle, runtime_directory);
+ return export_legacy_dbus_address(pamh, runtime_directory);
}
static int setup_environment(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
UserRecord *ur,
const char *runtime_directory,
const char *area,
int r;
- assert(handle);
+ assert(pamh);
assert(ur);
const char *h = ASSERT_PTR(user_record_home_directory(ur));
if (area) {
_cleanup_free_ char *j = path_join(h, "Areas", area);
if (!j)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
_cleanup_close_ int fd = -EBADF;
r = chase(j, /* root= */ NULL, CHASE_MUST_BE_DIRECTORY, &ha, &fd);
if (r < 0) {
/* Log the precise error */
- pam_syslog_errno(handle, LOG_WARNING, r, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory: %m", j, area);
+ pam_syslog_errno(pamh, LOG_WARNING, r, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory: %m", j, area);
/* Also tell the user directly at login, but a bit more vague */
- pam_info(handle, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
+ pam_info(pamh, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
area = NULL;
} else {
/* Validate that the target is definitely owned by user */
struct stat st;
if (fstat(fd, &st) < 0)
- return pam_syslog_errno(handle, LOG_ERR, errno, "Unable to fstat() target area directory '%s': %m", ha);
+ return pam_syslog_errno(pamh, LOG_ERR, errno, "Unable to fstat() target area directory '%s': %m", ha);
if (st.st_uid != ur->uid) {
- pam_syslog(handle, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
+ pam_syslog(pamh, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
/* Also tell the user directly at login. */
- pam_info(handle, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
+ pam_info(pamh, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
area = NULL;
} else {
/* All good, now make a copy of the area string, since we quite likely are
* update_environment() call below */
area_copy = strdup(area);
if (!area_copy)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- pam_debug_syslog(handle, debug, "Area '%s' selected, setting $HOME to '%s'.", area, ha);
+ pam_debug_syslog(pamh, debug, "Area '%s' selected, setting $HOME to '%s'.", area, ha);
h = ha;
area = area_copy;
}
}
}
- r = update_environment(handle, "XDG_AREA", area);
+ r = update_environment(pamh, "XDG_AREA", area);
if (r != PAM_SUCCESS)
return r;
- r = update_environment(handle, "HOME", h);
+ r = update_environment(pamh, "HOME", h);
if (r != PAM_SUCCESS)
return r;
- return setup_runtime_directory(handle, ur, runtime_directory, area);
+ return setup_runtime_directory(pamh, ur, runtime_directory, area);
}
-static int open_osc_context(pam_handle_t *handle, const char *session_type, UserRecord *ur, bool debug) {
+static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRecord *ur, bool debug) {
int r;
- assert(handle);
+ assert(pamh);
assert(ur);
/* If this is a TTY session, then output the session start OSC sequence */
if (!streq_ptr(session_type, "tty"))
return PAM_SUCCESS;
- const char *e = pam_getenv(handle, "TERM");
+ const char *e = pam_getenv(pamh, "TERM");
if (!e)
e = getenv("TERM");
if (streq_ptr(e, "dumb"))
* so that we don't delay tty hang-up. */
_cleanup_close_ int tty_opath_fd = fd_reopen(STDOUT_FILENO, O_PATH|O_CLOEXEC);
if (tty_opath_fd < 0)
- pam_debug_syslog_errno(handle, debug, tty_opath_fd, "Failed to pin TTY, ignoring: %m");
+ pam_debug_syslog_errno(pamh, debug, tty_opath_fd, "Failed to pin TTY, ignoring: %m");
else
tty_opath_fd = fd_move_above_stdio(tty_opath_fd);
sd_id128_t osc_id;
r = osc_context_open_session(
ur->user_name,
- pam_getenv(handle, "XDG_SESSION_ID"),
+ pam_getenv(pamh, "XDG_SESSION_ID"),
&osc,
&osc_id);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to prepare OSC sequence: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to prepare OSC sequence: %m");
r = loop_write(STDOUT_FILENO, osc, SIZE_MAX);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to write OSC sequence to TTY: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to write OSC sequence to TTY: %m");
/* Remember the OSC context id, so that we can close it cleanly later */
_cleanup_free_ sd_id128_t *osc_id_copy = newdup(sd_id128_t, &osc_id, 1);
if (!osc_id_copy)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
- r = pam_set_data(handle, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
+ r = pam_set_data(pamh, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM OSC sequence ID data: @PAMERR@");
TAKE_PTR(osc_id_copy);
if (tty_opath_fd >= 0) {
- r = pam_set_data(handle, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
+ r = pam_set_data(pamh, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to set PAM OSC sequence fd data: @PAMERR@");
TAKE_FD(tty_opath_fd);
return PAM_SUCCESS;
}
-static int close_osc_context(pam_handle_t *handle, bool debug) {
+static int close_osc_context(pam_handle_t *pamh, bool debug) {
int r;
- assert(handle);
+ assert(pamh);
const void *p;
int tty_opath_fd = -EBADF;
- r = pam_get_data(handle, "systemd.osc-context-fd", &p);
+ r = pam_get_data(pamh, "systemd.osc-context-fd", &p);
if (r == PAM_SUCCESS)
tty_opath_fd = PTR_TO_FD(p);
else if (r != PAM_NO_MODULE_DATA)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM OSC context fd: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM OSC context fd: @PAMERR@");
if (tty_opath_fd < 0)
return PAM_SUCCESS;
const sd_id128_t *osc_id = NULL;
- r = pam_get_data(handle, "systemd.osc-context-id", (const void**) &osc_id);
+ r = pam_get_data(pamh, "systemd.osc-context-id", (const void**) &osc_id);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM OSC context id data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM OSC context id data: @PAMERR@");
if (!osc_id)
return PAM_SUCCESS;
/* Now open the original TTY again, so that we can write on it */
_cleanup_close_ int fd = fd_reopen(tty_opath_fd, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
if (fd < 0) {
- pam_debug_syslog_errno(handle, debug, fd, "Failed to reopen TTY, ignoring: %m");
+ pam_debug_syslog_errno(pamh, debug, fd, "Failed to reopen TTY, ignoring: %m");
return PAM_SUCCESS;
}
_cleanup_free_ char *osc = NULL;
r = osc_context_close(*osc_id, &osc);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to prepare OSC sequence: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to prepare OSC sequence: %m");
/* When we are closing things, the TTY might not take our writes anymore. Accept that gracefully. */
r = loop_write(fd, osc, SIZE_MAX);
if (r < 0)
- pam_debug_syslog_errno(handle, debug, r, "Failed to write OSC sequence to TTY, ignoring: %m");
+ pam_debug_syslog_errno(pamh, debug, r, "Failed to write OSC sequence to TTY, ignoring: %m");
return PAM_SUCCESS;
}
_public_ PAM_EXTERN int pam_sm_open_session(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int flags,
int argc, const char **argv) {
int r;
- assert(handle);
+ assert(pamh);
r = dlopen_libpam();
if (r < 0)
uint64_t default_capability_bounding_set = CAP_MASK_UNSET, default_capability_ambient_set = CAP_MASK_UNSET;
const char *class_pam = NULL, *type_pam = NULL, *desktop_pam = NULL, *area_pam = NULL;
bool debug = false;
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
&class_pam,
&type_pam,
&default_capability_ambient_set) < 0)
return PAM_SESSION_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd: initializing...");
+ pam_debug_syslog(pamh, debug, "pam-systemd: initializing...");
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
- r = acquire_user_record(handle, &ur);
+ r = acquire_user_record(pamh, &ur);
if (r != PAM_SUCCESS)
return r;
SessionContext c = {};
r = pam_get_item_many(
- handle,
+ pamh,
PAM_SERVICE, &c.service,
PAM_XDISPLAY, &c.display,
PAM_TTY, &c.tty,
PAM_RUSER, &c.remote_user,
PAM_RHOST, &c.remote_host);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM items: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM items: @PAMERR@");
- c.seat = getenv_harder(handle, "XDG_SEAT", NULL);
- c.vtnr = getenv_harder_uint32(handle, "XDG_VTNR", 0);
- c.type = getenv_harder(handle, "XDG_SESSION_TYPE", type_pam);
- c.class = getenv_harder(handle, "XDG_SESSION_CLASS", class_pam);
- c.desktop = getenv_harder(handle, "XDG_SESSION_DESKTOP", desktop_pam);
- c.area = getenv_harder(handle, "XDG_AREA", area_pam);
- c.incomplete = getenv_harder_bool(handle, "XDG_SESSION_INCOMPLETE", false);
+ c.seat = getenv_harder(pamh, "XDG_SEAT", NULL);
+ c.vtnr = getenv_harder_uint32(pamh, "XDG_VTNR", 0);
+ c.type = getenv_harder(pamh, "XDG_SESSION_TYPE", type_pam);
+ c.class = getenv_harder(pamh, "XDG_SESSION_CLASS", class_pam);
+ c.desktop = getenv_harder(pamh, "XDG_SESSION_DESKTOP", desktop_pam);
+ c.area = getenv_harder(pamh, "XDG_AREA", area_pam);
+ c.incomplete = getenv_harder_bool(pamh, "XDG_SESSION_INCOMPLETE", false);
r = pam_get_data_many(
- handle,
+ pamh,
"systemd.memory_max", &c.memory_max,
"systemd.tasks_max", &c.tasks_max,
"systemd.cpu_weight", &c.cpu_weight,
"systemd.io_weight", &c.io_weight,
"systemd.runtime_max_sec", &c.runtime_max_sec);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get PAM data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM data: @PAMERR@");
- session_context_mangle(handle, &c, ur, debug);
+ session_context_mangle(pamh, &c, ur, debug);
_cleanup_free_ char *seat_buffer = NULL, *type_buffer = NULL, *runtime_dir = NULL;
- r = register_session(handle, &c, ur, debug, &seat_buffer, &type_buffer, &runtime_dir);
+ r = register_session(pamh, &c, ur, debug, &seat_buffer, &type_buffer, &runtime_dir);
if (r != PAM_SUCCESS)
return r;
- r = import_shell_credentials(handle, debug);
+ r = import_shell_credentials(pamh, debug);
if (r != PAM_SUCCESS)
return r;
- r = setup_environment(handle, ur, runtime_dir, c.area, debug);
+ r = setup_environment(pamh, ur, runtime_dir, c.area, debug);
if (r != PAM_SUCCESS)
return r;
if (default_capability_ambient_set == CAP_MASK_UNSET)
default_capability_ambient_set = pick_default_capability_ambient_set(ur, c.service, c.seat);
- r = apply_user_record_settings(handle, ur, debug, default_capability_bounding_set, default_capability_ambient_set);
+ r = apply_user_record_settings(pamh, ur, debug, default_capability_bounding_set, default_capability_ambient_set);
if (r != PAM_SUCCESS)
return r;
- return open_osc_context(handle, c.type, ur, debug);
+ return open_osc_context(pamh, c.type, ur, debug);
}
_public_ PAM_EXTERN int pam_sm_close_session(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int flags,
int argc, const char **argv) {
const char *id;
int r;
- assert(handle);
+ assert(pamh);
pam_log_setup();
- if (parse_argv(handle,
+ if (parse_argv(pamh,
argc, argv,
/* class= */ NULL,
/* type= */ NULL,
/* default_capability_ambient_set= */ NULL) < 0)
return PAM_SESSION_ERR;
- pam_debug_syslog(handle, debug, "pam-systemd: shutting down...");
+ pam_debug_syslog(pamh, debug, "pam-systemd: shutting down...");
/* Only release session if it wasn't pre-existing when we
* tried to create it */
- r = pam_get_data(handle, "systemd.existing", &existing);
+ r = pam_get_data(pamh, "systemd.existing", &existing);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r,
+ return pam_syslog_pam_error(pamh, LOG_ERR, r,
"Failed to get PAM systemd.existing data: @PAMERR@");
- (void) close_osc_context(handle, debug);
+ (void) close_osc_context(pamh, debug);
- id = pam_getenv(handle, "XDG_SESSION_ID");
+ id = pam_getenv(pamh, "XDG_SESSION_ID");
if (id && !existing) {
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
bool done = false;
r = sd_varlink_connect_address(&vl, "/run/systemd/io.systemd.Login");
if (r < 0)
- pam_debug_syslog_errno(handle, debug, r, "Failed to connect to logind via Varlink, falling back to D-Bus: %m");
+ pam_debug_syslog_errno(pamh, debug, r, "Failed to connect to logind via Varlink, falling back to D-Bus: %m");
else {
_cleanup_(sd_json_variant_unrefp) sd_json_variant *vreply = NULL;
const char *error_id = NULL;
&error_id,
SD_JSON_BUILD_PAIR_STRING("Id", id));
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r,
+ return pam_syslog_errno(pamh, LOG_ERR, r,
"Failed to issue io.systemd.Login.ReleaseSession varlink call: %m");
if (error_id)
- return pam_syslog_errno(handle, LOG_ERR, sd_varlink_error_to_errno(error_id, vreply),
+ return pam_syslog_errno(pamh, LOG_ERR, sd_varlink_error_to_errno(error_id, vreply),
"Varlink call io.systemd.Login.ReleaseSession failed: %s", error_id);
done = true;
/* Before we go and close the FIFO we need to tell logind that this is a clean session
* shutdown, so that it doesn't just go and slaughter us immediately after closing the fd */
- r = pam_acquire_bus_connection(handle, "pam-systemd", debug, &bus, &d);
+ r = pam_acquire_bus_connection(pamh, "pam-systemd", debug, &bus, &d);
if (r != PAM_SUCCESS)
return r;
r = bus_call_method(bus, bus_login_mgr, "ReleaseSession", &error, NULL, "s", id);
if (r < 0)
- return pam_syslog_pam_error(handle, LOG_ERR, PAM_SESSION_ERR,
+ return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SESSION_ERR,
"Failed to release session: %s", bus_error_message(&error, r));
}
}
static const char DEFAULT_KEYNAME[] = "cryptsetup";
_public_ PAM_EXTERN int pam_sm_authenticate(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int flags,
int argc, const char **argv) {
int r;
- assert(handle);
+ assert(pamh);
r = dlopen_libpam();
if (r < 0)
else if (streq(argv[i], "debug"))
debug = true;
else
- pam_syslog(handle, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
+ pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
}
- pam_debug_syslog(handle, debug, "pam-systemd-loadkey: initializing...");
+ pam_debug_syslog(pamh, debug, "pam-systemd-loadkey: initializing...");
/* Retrieve the key. */
serial = request_key("user", keyname, NULL, 0);
if (serial < 0) {
if (errno == ENOKEY) {
- pam_debug_syslog(handle, debug, "Key not found: %s", keyname);
+ pam_debug_syslog(pamh, debug, "Key not found: %s", keyname);
return PAM_AUTHINFO_UNAVAIL;
} else if (errno == EKEYEXPIRED) {
- pam_debug_syslog(handle, debug, "Key expired: %s", keyname);
+ pam_debug_syslog(pamh, debug, "Key expired: %s", keyname);
return PAM_AUTHINFO_UNAVAIL;
} else
- return pam_syslog_errno(handle, LOG_ERR, errno, "Failed to look up the key: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, errno, "Failed to look up the key: %m");
}
_cleanup_(erase_and_freep) void *p = NULL;
r = keyring_read(serial, &p, &n);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to read the key: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to read the key: %m");
/* Split the key by NUL. Set the last item as authtok. */
_cleanup_strv_free_erase_ char **passwords = strv_parse_nulstr(p, n);
if (!passwords)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
size_t passwords_len = strv_length(passwords);
if (passwords_len == 0) {
- pam_debug_syslog(handle, debug, "Key is empty.");
+ pam_debug_syslog(pamh, debug, "Key is empty.");
return PAM_AUTHINFO_UNAVAIL;
} else if (passwords_len > 1)
- pam_debug_syslog(handle, debug, "Multiple passwords found in the key. Using the last one.");
+ pam_debug_syslog(pamh, debug, "Multiple passwords found in the key. Using the last one.");
- r = pam_set_item(handle, PAM_AUTHTOK, passwords[passwords_len - 1]);
+ r = pam_set_item(pamh, PAM_AUTHTOK, passwords[passwords_len - 1]);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
return PAM_SUCCESS;
}
_public_ PAM_EXTERN int pam_sm_setcred(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
int flags,
int argc, const char **argv) {
return ERRNO_VALUE(error) == ENOMEM ? PAM_BUF_ERR : PAM_SERVICE_ERR;
}
-int pam_syslog_errno(pam_handle_t *handle, int level, int error, const char *format, ...) {
+int pam_syslog_errno(pam_handle_t *pamh, int level, int error, const char *format, ...) {
va_list ap;
error = ERRNO_VALUE(error);
LOCAL_ERRNO(error);
va_start(ap, format);
- sym_pam_vsyslog(handle, level, format, ap);
+ sym_pam_vsyslog(pamh, level, format, ap);
va_end(ap);
return errno_to_pam_error(error);
}
-int pam_syslog_pam_error(pam_handle_t *handle, int level, int error, const char *format, ...) {
+int pam_syslog_pam_error(pam_handle_t *pamh, int level, int error, const char *format, ...) {
/* This wraps pam_syslog() but will replace @PAMERR@ with a string from pam_strerror().
* @PAMERR@ must be at the very end. */
const char *p = endswith(format, "@PAMERR@");
if (p) {
- const char *pamerr = sym_pam_strerror(handle, error);
+ const char *pamerr = sym_pam_strerror(pamh, error);
if (strchr(pamerr, '%'))
pamerr = "n/a"; /* We cannot have any formatting chars */
xsprintf(buf, "%.*s%s", (int)(p - format), format, pamerr);
DISABLE_WARNING_FORMAT_NONLITERAL;
- sym_pam_vsyslog(handle, level, buf, ap);
+ sym_pam_vsyslog(pamh, level, buf, ap);
REENABLE_WARNING;
} else
- sym_pam_vsyslog(handle, level, format, ap);
+ sym_pam_vsyslog(pamh, level, format, ap);
va_end(ap);
DEFINE_TRIVIAL_CLEANUP_FUNC(PamBusData*, pam_bus_data_free);
-static void pam_bus_data_destroy(pam_handle_t *handle, void *data, int error_status) {
+static void pam_bus_data_destroy(pam_handle_t *pamh, void *data, int error_status) {
/* Destructor when called from PAM. Note that error_status is supposed to tell us via PAM_DATA_SILENT
* whether we are called in a forked off child of the PAM session or in the original parent. We don't
* bother with that however, and instead rely on the PID checks that sd_bus_flush_close_unref() does
if (FLAGS_SET(error_status, PAM_DATA_SILENT) &&
d->bus && bus_origin_changed(d->bus))
/* Please adjust test/units/end.sh when updating the log message. */
- sym_pam_syslog(handle, LOG_DEBUG,
+ sym_pam_syslog(pamh, LOG_DEBUG,
"Warning: cannot close sd-bus connection (%s) after fork when it was opened before the fork.",
strna(d->cache_id));
void pam_bus_data_disconnectp(PamBusData **_d) {
PamBusData *d = *ASSERT_PTR(_d);
- pam_handle_t *handle;
+ pam_handle_t *pamh;
int r;
/* Disconnects the connection explicitly (for use via _cleanup_()) when called */
if (!d)
return;
- handle = ASSERT_PTR(d->pam_handle); /* Keep a reference to the session even after 'd' might be invalidated */
+ pamh = ASSERT_PTR(d->pam_handle); /* Keep a reference to the session even after 'd' might be invalidated */
- r = sym_pam_set_data(handle, ASSERT_PTR(d->cache_id), NULL, NULL);
+ r = sym_pam_set_data(pamh, ASSERT_PTR(d->cache_id), NULL, NULL);
if (r != PAM_SUCCESS)
- pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to release PAM user record data, ignoring: @PAMERR@");
+ pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to release PAM user record data, ignoring: @PAMERR@");
/* Note, the pam_set_data() call will invalidate 'd', don't access here anymore */
}
int pam_acquire_bus_connection(
- pam_handle_t *handle,
+ pam_handle_t *pamh,
const char *module_name,
bool debug,
sd_bus **ret_bus,
_cleanup_free_ char *cache_id = NULL;
int r;
- assert(handle);
+ assert(pamh);
assert(module_name);
assert(ret_bus);
cache_id = pam_make_bus_cache_id(module_name);
if (!cache_id)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
/* We cache the bus connection so that we can share it between the session and the authentication hooks */
- r = sym_pam_get_data(handle, cache_id, (const void**) &d);
+ r = sym_pam_get_data(pamh, cache_id, (const void**) &d);
if (r == PAM_SUCCESS && d)
goto success;
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
d = new(PamBusData, 1);
if (!d)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
*d = (PamBusData) {
.cache_id = TAKE_PTR(cache_id),
- .pam_handle = handle,
+ .pam_handle = pamh,
};
r = sd_bus_open_system(&d->bus);
if (r < 0)
- return pam_syslog_errno(handle, LOG_ERR, r, "Failed to connect to system bus: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to connect to system bus: %m");
- r = sym_pam_set_data(handle, d->cache_id, d, pam_bus_data_destroy);
+ r = sym_pam_set_data(pamh, d->cache_id, d, pam_bus_data_destroy);
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
- pam_debug_syslog(handle, debug, "New sd-bus connection (%s) opened.", d->cache_id);
+ pam_debug_syslog(pamh, debug, "New sd-bus connection (%s) opened.", d->cache_id);
success:
*ret_bus = sd_bus_ref(d->bus);
return PAM_SUCCESS;
}
-int pam_get_bus_data(
- pam_handle_t *handle,
- const char *module_name,
- PamBusData **ret) {
-
+int pam_get_bus_data(pam_handle_t *pamh, const char *module_name, PamBusData **ret) {
PamBusData *d = NULL;
_cleanup_free_ char *cache_id = NULL;
int r;
- assert(handle);
+ assert(pamh);
assert(module_name);
assert(ret);
cache_id = pam_make_bus_cache_id(module_name);
if (!cache_id)
- return pam_log_oom(handle);
+ return pam_log_oom(pamh);
/* We cache the bus connection so that we can share it between the session and the authentication hooks */
- r = sym_pam_get_data(handle, cache_id, (const void**) &d);
+ r = sym_pam_get_data(pamh, cache_id, (const void**) &d);
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
- return pam_syslog_pam_error(handle, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get bus connection: @PAMERR@");
*ret = d;
return PAM_SUCCESS;
}
-void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status) {
+void pam_cleanup_free(pam_handle_t *pamh, void *data, int error_status) {
/* A generic destructor for pam_set_data() that just frees the specified data */
free(data);
}
-void pam_cleanup_close(pam_handle_t *handle, void *data, int error_status) {
+void pam_cleanup_close(pam_handle_t *pamh, void *data, int error_status) {
/* A generic destructor for pam_set_data() that just closes the specified fd.
*
safe_close(PTR_TO_FD(data));
}
-int pam_get_item_many_internal(pam_handle_t *handle, ...) {
+int pam_get_item_many_internal(pam_handle_t *pamh, ...) {
va_list ap;
int r;
- assert(handle);
+ assert(pamh);
- va_start(ap, handle);
+ va_start(ap, pamh);
for (;;) {
int item_type = va_arg(ap, int);
if (item_type <= 0) {
}
const void **value = ASSERT_PTR(va_arg(ap, const void **));
- r = sym_pam_get_item(handle, item_type, value);
+ r = sym_pam_get_item(pamh, item_type, value);
if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS))
break;
}
return r;
}
-int pam_get_data_many_internal(pam_handle_t *handle, ...) {
+int pam_get_data_many_internal(pam_handle_t *pamh, ...) {
va_list ap;
int r;
- assert(handle);
+ assert(pamh);
- va_start(ap, handle);
+ va_start(ap, pamh);
for (;;) {
const char *data_name = va_arg(ap, const char *);
if (!data_name) {
}
const void **value = ASSERT_PTR(va_arg(ap, const void **));
- r = sym_pam_get_data(handle, data_name, value);
+ r = sym_pam_get_data(pamh, data_name, value);
if (!IN_SET(r, PAM_NO_MODULE_DATA, PAM_SUCCESS))
break;
}
return r;
}
-int pam_prompt_graceful(pam_handle_t *handle, int style, char **ret_response, const char *fmt, ...) {
+int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, const char *fmt, ...) {
va_list args;
int r;
- assert(handle);
+ assert(pamh);
assert(fmt);
/* This is just like pam_prompt(), but does not noisily (i.e. beyond LOG_DEBUG) log on its own, but leaves that to the caller */
return PAM_BUF_ERR;
const struct pam_conv *conv = NULL;
- r = sym_pam_get_item(handle, PAM_CONV, (const void**) &conv);
+ r = sym_pam_get_item(pamh, PAM_CONV, (const void**) &conv);
if (!IN_SET(r, PAM_SUCCESS, PAM_BAD_ITEM))
- return pam_syslog_pam_error(handle, LOG_DEBUG, r, "Failed to get conversation function structure: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_DEBUG, r, "Failed to get conversation function structure: @PAMERR@");
if (!conv || !conv->conv) {
- sym_pam_syslog(handle, LOG_DEBUG, "No conversation function.");
+ sym_pam_syslog(pamh, LOG_DEBUG, "No conversation function.");
return PAM_SYSTEM_ERR;
}
r = conv->conv(1, &pmessage, &response, conv->appdata_ptr);
_cleanup_(erase_and_freep) char *rr = response ? response->resp : NULL; /* make sure string is freed + erased */
if (r != PAM_SUCCESS)
- return pam_syslog_pam_error(handle, LOG_DEBUG, r, "Conversation function failed: @PAMERR@");
+ return pam_syslog_pam_error(pamh, LOG_DEBUG, r, "Conversation function failed: @PAMERR@");
if (ret_response)
*ret_response = TAKE_PTR(rr);
int errno_to_pam_error(int error) _const_;
-int pam_syslog_errno(pam_handle_t *handle, int level, int error, const char *format, ...) _printf_(4,5);
+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 *handle, 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, ...) \
errno_to_pam_error(_error); \
})
-static inline int pam_log_oom(pam_handle_t *handle) {
+static inline int pam_log_oom(pam_handle_t *pamh) {
/* This is like log_oom(), but uses PAM logging */
- return pam_syslog_errno(handle, LOG_ERR, ENOMEM, "Out of memory.");
+ return pam_syslog_errno(pamh, LOG_ERR, ENOMEM, "Out of memory.");
}
-static inline int pam_bus_log_create_error(pam_handle_t *handle, int r) {
+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(handle, LOG_ERR, r, "Failed to create bus message: %m");
+ 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 *handle, int r) {
+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(handle, LOG_ERR, r, "Failed to parse bus message: %m");
+ return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to parse bus message: %m");
}
typedef struct PamBusData PamBusData;
/* 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 *handle,
+ 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 *handle, const char *module_name, PamBusData **ret);
+int pam_get_bus_data(pam_handle_t *pamh, const char *module_name, PamBusData **ret);
-void pam_cleanup_free(pam_handle_t *handle, void *data, int error_status);
-void pam_cleanup_close(pam_handle_t *handle, void *data, int error_status);
+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 *handle, ...);
+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 *handle, ...) _sentinel_;
+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 *handle, int style, char **ret_response, const char *fmt, ...) _printf_(4,5);
+int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, const char *fmt, ...) _printf_(4,5);
#else