comparison src/libpam/handle.rs @ 102:94eb11cb1798 default tip

Improve documentation for pam_start.
author Paul Fisher <paul@pfish.zone>
date Tue, 24 Jun 2025 18:11:38 -0400
parents 94b51fa4f797
children
comparison
equal deleted inserted replaced
101:94b51fa4f797 102:94eb11cb1798
35 /// The handle itself. 35 /// The handle itself.
36 handle: HandleWrap, 36 handle: HandleWrap,
37 /// The last return value from the handle. 37 /// The last return value from the handle.
38 last_return: Cell<Result<()>>, 38 last_return: Cell<Result<()>>,
39 /// If set, the Conversation that this PAM handle owns. 39 /// If set, the Conversation that this PAM handle owns.
40 ///
41 /// We have to hold on to this because the PAM specification doesn't
42 /// actually say what the PAM library should do with a passed-in
43 /// conversation. Linux-PAM copies the contents of the `pam_conv` struct
44 /// that you pass in to `pam_start`, but OpenPAM uses the pointer itself,
45 /// so you have to keep it in one place.
40 conversation: Option<Box<LibPamConversation<'a>>>, 46 conversation: Option<Box<LibPamConversation<'a>>>,
41 } 47 }
42 48
43 #[derive(Debug, PartialEq)] 49 #[derive(Debug, PartialEq)]
44 pub struct HandleBuilder { 50 pub struct HandleBuilder {
45 service_name: String, 51 service_name: String,
46 username: Option<String>, 52 username: Option<String>,
47 } 53 }
48 54
49 impl HandleBuilder { 55 impl HandleBuilder {
50 /// Creates a new HandleBuilder for the given service.
51 fn new(service_name: String) -> Self {
52 Self {
53 service_name,
54 username: Default::default(),
55 }
56 }
57 /// Updates the service name. 56 /// Updates the service name.
58 pub fn service_name(mut self, service_name: String) -> Self { 57 pub fn service_name(mut self, service_name: String) -> Self {
59 self.service_name = service_name; 58 self.service_name = service_name;
60 self 59 self
61 } 60 }
62 /// Updates the username. 61 /// Sets the username. Setting this will avoid the need for an extra
62 /// round trip through the conversation and may otherwise improve
63 /// the login experience.
63 pub fn username(mut self, username: String) -> Self { 64 pub fn username(mut self, username: String) -> Self {
64 self.username = Some(username); 65 self.username = Some(username);
65 self 66 self
66 } 67 }
67 68 /// Builds a PAM handle and starts the transaction.
68 pub fn build(self, conv: &impl Conversation) -> Result<OwnedLibPamHandle> { 69 pub fn build(self, conv: &impl Conversation) -> Result<OwnedLibPamHandle> {
69 OwnedLibPamHandle::start(self.service_name, self.username, conv) 70 OwnedLibPamHandle::start(self.service_name, self.username, conv)
70 } 71 }
71 } 72 }
72 73
73 impl OwnedLibPamHandle<'_> { 74 impl OwnedLibPamHandle<'_> {
75 /// Creates a builder to start a PAM transaction for the given service.
76 ///
77 /// The service name is what controls the steps and checks PAM goes through
78 /// when authenticating a user. This corresponds to the configuration file
79 /// named <code>/etc/pam.d/<var>service_name</var></code>.
80 ///
81 /// For more information, see the [`pam_start` man page][man], or
82 /// [`pam_start` in the PAM Application Developers' Guide][adg].
83 ///
84 /// [man]: https://www.man7.org/linux/man-pages/man3/pam_start.3.html
85 /// [adg]: https://www.chiark.greenend.org.uk/doc/libpam-doc/html/adg-interface-by-app-expected.html#adg-pam_start
74 pub fn build_with_service(service_name: String) -> HandleBuilder { 86 pub fn build_with_service(service_name: String) -> HandleBuilder {
75 HandleBuilder::new(service_name) 87 HandleBuilder { service_name, username: None }
76 } 88 }
89
77 fn start( 90 fn start(
78 service_name: String, 91 service_name: String,
79 username: Option<String>, 92 username: Option<String>,
80 conversation: &impl Conversation, 93 conversation: &impl Conversation,
81 ) -> Result<Self> { 94 ) -> Result<Self> {