static errno_t get_p11_child_write_buffer(TALLOC_CTX *mem_ctx, struct pam_data *pd, uint8_t **_buf, size_t *_len) { int ret; uint8_t *buf; size_t len; const char *pin = NULL; if (pd == NULL || pd->authtok == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing authtok.\n"); return EINVAL; } switch (sss_authtok_get_type(pd->authtok)) { case SSS_AUTHTOK_TYPE_SC_PIN: ret = sss_authtok_get_sc_pin(pd->authtok, &pin, &len); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_authtok_get_sc_pin failed.\n"); return ret; } if (pin == NULL || len == 0) { DEBUG(SSSDBG_CRIT_FAILURE, "Missing PIN.\n"); return EINVAL; } buf = talloc_size(mem_ctx, len); if (buf == NULL) { DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n"); return ENOMEM; } safealign_memcpy(buf, pin, len, NULL); break; case SSS_AUTHTOK_TYPE_SC_KEYPAD: /* Nothing to send */ len = 0; buf = NULL; break; default: DEBUG(SSSDBG_CRIT_FAILURE, "Unsupported authtok type [%d].\n", sss_authtok_get_type(pd->authtok)); return EINVAL; } *_len = len; *_buf = buf; return EOK; }
bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) { dbus_bool_t db_ret; const char *service; const char *tty; const char *ruser; const char *rhost; uint32_t authtok_type; int authtok_length; uint8_t *authtok_data; uint32_t new_authtok_type; int new_authtok_length; uint8_t *new_authtok_data; int32_t pd_priv; int32_t pd_cmd; if (pd->user == NULL) return false; service = pd->service ? pd->service : ""; tty = pd->tty ? pd->tty : ""; ruser = pd->ruser ? pd->ruser : ""; rhost = pd->rhost ? pd->rhost : ""; authtok_type = (uint32_t)sss_authtok_get_type(pd->authtok); authtok_data = sss_authtok_get_data(pd->authtok); authtok_length = sss_authtok_get_size(pd->authtok); new_authtok_type = (uint32_t)sss_authtok_get_type(pd->newauthtok); new_authtok_data = sss_authtok_get_data(pd->newauthtok); new_authtok_length = sss_authtok_get_size(pd->newauthtok); pd_priv = pd->priv; pd_cmd = pd->cmd; db_ret = dbus_message_append_args(msg, DBUS_TYPE_INT32, &pd_cmd, DBUS_TYPE_STRING, &(pd->user), DBUS_TYPE_STRING, &(pd->domain), DBUS_TYPE_STRING, &service, DBUS_TYPE_STRING, &tty, DBUS_TYPE_STRING, &ruser, DBUS_TYPE_STRING, &rhost, DBUS_TYPE_UINT32, &authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &authtok_data, authtok_length, DBUS_TYPE_UINT32, &new_authtok_type, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &new_authtok_data, new_authtok_length, DBUS_TYPE_INT32, &pd_priv, DBUS_TYPE_UINT32, &(pd->cli_pid), DBUS_TYPE_INVALID); return db_ret; }
bool may_do_cert_auth(struct pam_ctx *pctx, struct pam_data *pd) { size_t c; const char *sc_services[] = { "login", "su", "su-l", "gdm-smartcard", "gdm-password", "kdm", "sudo", "sudo-i", "gnome-screensaver", NULL }; if (!pctx->cert_auth) { return false; } if (pd->cmd != SSS_PAM_PREAUTH && pd->cmd != SSS_PAM_AUTHENTICATE) { return false; } if (pd->cmd == SSS_PAM_AUTHENTICATE && sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_SC_PIN && sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_SC_KEYPAD) { return false; } /* TODO: make services configurable */ if (pd->service == NULL || *pd->service == '\0') { return false; } for (c = 0; sc_services[c] != NULL; c++) { if (strcmp(pd->service, sc_services[c]) == 0) { break; } } if (sc_services[c] == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, "Smartcard authentication for service [%s] not supported.\n", pd->service); return false; } return true; }
static void krb5_auth_cache_creds(struct krb5_ctx *krb5_ctx, struct sss_domain_info *domain, struct confdb_ctx *cdb, struct pam_data *pd, uid_t uid, int *pam_status, int *dp_err) { const char *password = NULL; errno_t ret; if (sss_authtok_get_type(pd->authtok) != SSS_AUTHTOK_TYPE_PASSWORD) { DEBUG(SSSDBG_MINOR_FAILURE, "Delayed authentication is only available for password " "authentication (single factor).\n"); return; } ret = sss_authtok_get_password(pd->authtok, &password, NULL); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get password [%d] %s\n", ret, strerror(ret)); *pam_status = PAM_SYSTEM_ERR; *dp_err = DP_ERR_OK; return; } ret = sysdb_cache_auth(domain, pd->user, password, cdb, true, NULL, NULL); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Offline authentication failed\n"); *pam_status = cached_login_pam_status(ret); *dp_err = DP_ERR_OK; return; } ret = add_user_to_delayed_online_authentication(krb5_ctx, pd, uid); if (ret != EOK) { /* This error is not fatal */ DEBUG(SSSDBG_CRIT_FAILURE, "add_user_to_delayed_online_authentication failed.\n"); } *pam_status = PAM_AUTHINFO_UNAVAIL; *dp_err = DP_ERR_OFFLINE; }
static void krb5_auth_store_creds(struct sss_domain_info *domain, struct pam_data *pd) { const char *password = NULL; const char *fa2; size_t password_len; size_t fa2_len = 0; int ret = EOK; switch(pd->cmd) { case SSS_CMD_RENEW: /* The authtok is set to the credential cache * during renewal. We don't want to save this * as the cached password. */ break; case SSS_PAM_PREAUTH: /* There are no credentials available during pre-authentication, * nothing to do. */ break; case SSS_PAM_AUTHENTICATE: case SSS_PAM_CHAUTHTOK_PRELIM: if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_2FA) { ret = sss_authtok_get_2fa(pd->authtok, &password, &password_len, &fa2, &fa2_len); if (ret == EOK && password_len < domain->cache_credentials_min_ff_length) { DEBUG(SSSDBG_FATAL_FAILURE, "First factor is too short to be cache, " "minimum length is [%u].\n", domain->cache_credentials_min_ff_length); ret = EINVAL; } } else if (sss_authtok_get_type(pd->authtok) == SSS_AUTHTOK_TYPE_PASSWORD) { ret = sss_authtok_get_password(pd->authtok, &password, NULL); } else { DEBUG(SSSDBG_MINOR_FAILURE, "Cannot cache authtok type [%d].\n", sss_authtok_get_type(pd->authtok)); ret = EINVAL; } break; case SSS_PAM_CHAUTHTOK: ret = sss_authtok_get_password(pd->newauthtok, &password, NULL); break; default: DEBUG(SSSDBG_FATAL_FAILURE, "unsupported PAM command [%d].\n", pd->cmd); } if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get password [%d] %s\n", ret, strerror(ret)); /* password caching failures are not fatal errors */ return; } if (password == NULL) { if (pd->cmd != SSS_CMD_RENEW && pd->cmd != SSS_PAM_PREAUTH) { DEBUG(SSSDBG_FATAL_FAILURE, "password not available, offline auth may not work.\n"); /* password caching failures are not fatal errors */ } return; } ret = sysdb_cache_password_ex(domain, pd->user, password, sss_authtok_get_type(pd->authtok), fa2_len); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to cache password, offline auth may not work." " (%d)[%s]!?\n", ret, strerror(ret)); /* password caching failures are not fatal errors */ } }