-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix issues with username not changing with set_credentials #14
base: master
Are you sure you want to change the base?
Conversation
Thanks for the PR! The issue is that the username is not queried again via the prompt if authentication fails once right?? I am actually not sure what should happen in this case as it depends on how the In any case I am not sure if manually calling |
Another more intuitive way would be to set the PAM_USER in the set_credentials function. And that is what I wanted to do originally. The problem with that is that the PasswordConv does not have access to the pam_handle. The problem happens even when no user is given in pam_start. The prompt_echo function will never be called more that once by PAM(so long as all modules use pam_get_user). I think it would be fine to create a new handle for each user, but then I feel like the set_credentials function should not accept username? Or at least document the fact that the username won't take effect if an authentication has been attempted. |
That's most certainly a good idea anyways. We should probably do that.
That can be fixed by passing the handle as |
Could it? If so I don't understand how. Afaik if we want the |
You're completely right, I forgot that we pass the |
I tried to make a Handler struct that holds both the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments and afterwards this should be ready.
I am not quite sure about the API, so I might iterate some more on it (pam
is 0.X for a reason ;)) but I'll merge it for now and see what I can come up with.
use crate::{PamError, PamReturnCode}; | ||
|
||
pub trait ConversationHandler<'a, C>: std::ops::Deref<Target = C> + DerefMut<Target = C> { | ||
fn create(conversation: Box<C>, handle: &'a mut PamHandle) -> Self; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call this new
to align with existing conventions
fn create(conversation: Box<C>, handle: &'a mut PamHandle) -> Self; | |
fn new(conversation: Box<C>, handle: &'a mut PamHandle) -> Self; |
pub trait ConversationHandler<'a, C>: std::ops::Deref<Target = C> + DerefMut<Target = C> { | ||
fn create(conversation: Box<C>, handle: &'a mut PamHandle) -> Self; | ||
fn handle_mut(this: &mut Self) -> &mut PamHandle; | ||
fn handle(this: &Self) -> &PamHandle; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be my OCD kicking in, but would you swap there two lines? You already implement those two methods in the other order below.
fn handle(this: &Self) -> &PamHandle; | ||
} | ||
|
||
pub struct DefaultHandler<'a, C> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite convinced by that name, but I can't come up with something better..
Yeah, I don't really like it either. I think maybe it would be better to just document the way it works for now. And then you can experiment some with the API to find something that is more intuitive. Sorry about the churn though. And I'll be sure to let you know if I find another solution, for now I think I will just be using the 'hack' in |
I have some problems with the
set_credendials
function, changing the password works fine but not the username. It seems like pam only ever calls theecho_prompt
once. I think the reason for this is that e.g.pam_unix.so
uses thepam_get_user
function. The documentation says that the returned value is the user specified bypam_start
, and if that's null thePAM_USER
item, and finally if that's null it tries the pam conversation. The documentation also says it sets the PAM_USER item. So the next time authentication is attempted the user is just read from PAM_USER, not from the conversation.