This reverts commit ecf6b7c323.
The idea of the commit was to make device failures less fatal to the
system. Unfortunately, we can fail quickly in this case, and returning
PAM_AUTH_ERR means that the user might run into a retry limit due to
this.
Go back to reporting PAM_AUTHINFO_UNAVAIL, it appears as the lesser evil
right now. Ideally we want to a way to tell the upper stack to retry
authentication whenever there is a good opportunity, but to not consider
it as an authentication failure.
fprintd only needs very few syscalls. Mainly normal IO operations and
ioctl for USB access. All of this is covered by @system-service, we
could likely restrict it quite a bit more though.
If the device supports listing prints, then we can do more targeted
deletes once the storage runs out. As such, do not try to clear the
storage on first enroll (therefore allowing dual boot setups to work to
a limited degree).
Clear the device storage before we enroll the first print. At that
point, we know that the storage should be completely empty and we have
no way of deleting "garbage" prints later if the device does not support
listing prints.
This makes little sense. Users should delete the finger before trying to
enroll the same one again. So throw an error at them from EnrollStart
right away.
Fixes: #95
Always do an identify step before starting an enroll. If we find an
existing print, delete or throw an error depending on what is
appropriate.
Doing this ensures that we should not get duplicate prints system wide.
This means we will be able to identify the user that is trying to log
in. But more importantly, we need to do these checks for MoC devices,
which always run "identify" against all device stored prints rather than
the passed gallery.
During VerifyStart we may return early if there are no enrolled prints.
In such case we don't require the verification to be stopped if we're
using identification, but in the verification case we may leave the
device into the verification state.
So ensure we only set the device current state only when we're about to
start it.
Add tests ensuring those cases
The user may have some invalid prints saved (like the ones enrolled with
fprintd 1) in the storage, this lead to list such prints as enrolled but
they're actually not valid.
So load the prints to ensure that those are of the valid type instead of
just discovering them.
We may make just store.discover_prints to be aware of this, but this
would break some assumptions we do in tests, so better to go this way.
We may want to be able to load the user prints to check whether they
are usable, so add an utility function for this.
And use it also in load_all_prints().
It might make sense to push this into the storage layer. But, overall,
it is OK to live here, and if we do make changes on the storage layer we
probably want to change more than just this.
If something under the hood failed with a generic device error we'd just
mark the PAM module not available, this is probably too much as it may
just be due to a device temporary error.
So make it stop but allow the loading system to retry with it
Loading saved prints may lead to an error if they were stored long time
ago and so they're using a wrong format.
In such case we list the prints as available even though they are really
not, so the PAM module won't return PAM_AUTHINFO_UNAVAIL as in the
no-prints case but PAM_USER_UNKNOWN.
This will lead some auth systems (such as gdm) to keep retrying using
PAM fprintd module, even if it's not really available.