From b4f53045659d09499ac082f93c741cb196f5a5c1 Mon Sep 17 00:00:00 2001 From: Rob Johnson Date: Mon, 3 Jun 2013 08:45:11 -0400 Subject: [PATCH] pam: return PAM_UNKNOWN_USER when user is unenrolled This commit makes pam_fprintd return PAM_UNKNOWN_USER when the user has not enrolled a fingerprint. This lets the administrator set up pam_fprintd as a required authentication, method, but only for users that have enrolled a fingerprint, as such: auth [success=ok user_unknown=ignore default=die] pam_fprintd.so max_tries=1 timeout=-1 auth [success=1 default=ignore] pam_unix.so nullok_secure auth requisite pam_deny.so With this config, users w/o an enrolled fingerprint will just be asked for a password. Users with an enrolled fingerprint will required to login using both their fingerprint and a password. https://bugs.freedesktop.org/show_bug.cgi?id=64781 --- pam/pam_fprintd.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pam/pam_fprintd.c b/pam/pam_fprintd.c index 7e1f954..0f5e5a4 100644 --- a/pam/pam_fprintd.c +++ b/pam/pam_fprintd.c @@ -290,60 +290,63 @@ static int do_verify(GMainLoop *loop, pam_handle_t *pamh, DBusGProxy *dev, gbool if (has_multiple_devices) data->driver = g_value_dup_string (g_hash_table_lookup (props, "name")); scan_type = g_value_dup_string (g_hash_table_lookup (props, "scan-type")); if (g_str_equal (scan_type, "swipe")) data->is_swipe = TRUE; g_hash_table_destroy (props); } g_object_unref (p); dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_STRING, G_TYPE_BOOLEAN, NULL); dbus_g_proxy_add_signal(dev, "VerifyFingerSelected", G_TYPE_STRING, NULL); dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), data, NULL); dbus_g_proxy_connect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected), data, NULL); ret = PAM_AUTH_ERR; while (ret == PAM_AUTH_ERR && data->max_tries > 0) { GSource *source; /* Set up the timeout on our non-default context */ source = g_timeout_source_new_seconds (timeout); g_source_attach (source, g_main_loop_get_context (loop)); g_source_set_callback (source, verify_timeout_cb, data, NULL); data->timed_out = FALSE; if (!dbus_g_proxy_call (dev, "VerifyStart", &error, G_TYPE_STRING, "any", G_TYPE_INVALID, G_TYPE_INVALID)) { + if (dbus_g_error_has_name(error, "net.reactivated.Fprint.Error.NoEnrolledPrints")) + ret = PAM_USER_UNKNOWN; + D(pamh, "VerifyStart failed: %s", error->message); g_error_free (error); g_source_destroy (source); g_source_unref (source); break; } g_main_loop_run (loop); g_source_destroy (source); g_source_unref (source); /* Ignore errors from VerifyStop */ dbus_g_proxy_call (dev, "VerifyStop", NULL, G_TYPE_INVALID, G_TYPE_INVALID); if (data->timed_out) { ret = PAM_AUTHINFO_UNAVAIL; break; } else { if (g_str_equal (data->result, "verify-no-match")) { send_err_msg (data->pamh, "Failed to match fingerprint"); ret = PAM_AUTH_ERR; } else if (g_str_equal (data->result, "verify-match")) ret = PAM_SUCCESS; else if (g_str_equal (data->result, "verify-unknown-error")) ret = PAM_AUTHINFO_UNAVAIL; else if (g_str_equal (data->result, "verify-disconnected")) { ret = PAM_AUTHINFO_UNAVAIL; g_free (data->result); -- 1.8.2.1