annotate src/libpam/handle.rs @ 98:b87100c5eed4

Start on environment variables, and make pointers nicer. This starts work on the PAM environment handling, and in so doing, introduces the CHeapBox and CHeapString structs. These are analogous to Box and CString, but they're located on the C heap rather than being Rust-managed memory. This is because environment variables deal with even more pointers and it turns out we can lose a lot of manual freeing using homemade smart pointers.
author Paul Fisher <paul@pfish.zone>
date Tue, 24 Jun 2025 04:25:25 -0400
parents efe2f5f8b5b2
children 94b51fa4f797
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
1 use super::conversation::LibPamConversation;
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
2 use crate::constants::{ErrorCode, Result};
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
3 use crate::conv::Message;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
4 use crate::environ::EnvironMapMut;
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
5 use crate::handle::PamShared;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
6 use crate::libpam::environ::{LibPamEnviron, LibPamEnvironMut};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
7 pub use crate::libpam::pam_ffi::LibPamHandle;
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
8 use crate::libpam::{memory, pam_ffi};
92
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
9 use crate::logging::Level;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
10 use crate::{Conversation, EnvironMap, Flags, PamHandleApplication, PamHandleModule};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
11 use num_enum::{IntoPrimitive, TryFromPrimitive};
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
12 use std::cell::Cell;
92
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
13 use std::ffi::{c_char, c_int, CString};
90
f6186e41399b Miscellaneous fixes and cleanup:
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
14 use std::marker::PhantomData;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
15 use std::ops::{Deref, DerefMut};
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
16 use std::ptr;
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
17
92
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
18 /// Owner for a PAM handle.
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
19 struct HandleWrap(*mut LibPamHandle);
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
20
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
21 impl Deref for HandleWrap {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
22 type Target = LibPamHandle;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
23 fn deref(&self) -> &Self::Target {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
24 unsafe { &*self.0 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
25 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
26 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
27
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
28 impl DerefMut for HandleWrap {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
29 fn deref_mut(&mut self) -> &mut Self::Target {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
30 unsafe { &mut *self.0 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
31 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
32 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
33
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
34 /// An owned PAM handle.
90
f6186e41399b Miscellaneous fixes and cleanup:
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
35 pub struct OwnedLibPamHandle<'a> {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
36 handle: HandleWrap,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
37 last_return: Cell<Result<()>>,
90
f6186e41399b Miscellaneous fixes and cleanup:
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
38 _conversation_lifetime: PhantomData<&'a mut ()>,
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
39 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
40
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
41 #[derive(Debug, PartialEq)]
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
42 pub struct HandleBuilder {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
43 service_name: String,
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
44 username: Option<String>,
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
45 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
46
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
47 impl HandleBuilder {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
48 /// Creates a new HandleBuilder for the given service.
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
49 fn new(service_name: String) -> Self {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
50 Self {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
51 service_name,
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
52 username: Default::default(),
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
53 }
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
54 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
55 /// Updates the service name.
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
56 pub fn service_name(mut self, service_name: String) -> Self {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
57 self.service_name = service_name;
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
58 self
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
59 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
60 /// Updates the username.
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
61 pub fn username(mut self, username: String) -> Self {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
62 self.username = Some(username);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
63 self
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
64 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
65
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
66 pub fn build(self, conv: &impl Conversation) -> Result<OwnedLibPamHandle> {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
67 OwnedLibPamHandle::start(self.service_name, self.username, conv)
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
68 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
69 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
70
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
71 impl OwnedLibPamHandle<'_> {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
72 pub fn build_with_service(service_name: String) -> HandleBuilder {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
73 HandleBuilder::new(service_name)
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
74 }
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
75 fn start(
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
76 service_name: String,
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
77 username: Option<String>,
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
78 conversation: &impl Conversation,
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
79 ) -> Result<Self> {
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
80 let conv = LibPamConversation::wrap(conversation);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
81 let service_cstr = CString::new(service_name).map_err(|_| ErrorCode::ConversationError)?;
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
82 let username_cstr = memory::prompt_ptr(memory::option_cstr(username.as_deref())?.as_ref());
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
83
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
84 let mut handle: *mut LibPamHandle = ptr::null_mut();
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
85 // SAFETY: We've set everything up properly to call `pam_start`.
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
86 // The returned value will be a valid pointer provided the result is OK.
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
87 let result =
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
88 unsafe { pam_ffi::pam_start(service_cstr.as_ptr(), username_cstr, &conv, &mut handle) };
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
89 ErrorCode::result_from(result)?;
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
90 Ok(Self {
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
91 handle: HandleWrap(handle),
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
92 last_return: Cell::new(Ok(())),
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
93 _conversation_lifetime: Default::default(),
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
94 })
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
95 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
96 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
98 impl PamHandleApplication for OwnedLibPamHandle<'_> {
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
99 fn authenticate(&mut self, flags: Flags) -> Result<()> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
100 let ret = unsafe { pam_ffi::pam_authenticate(self.handle.0, flags.bits() as c_int) };
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
101 let result = ErrorCode::result_from(ret);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
102 self.last_return.set(result);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
103 result
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
104 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
105
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
106 fn account_management(&mut self, flags: Flags) -> Result<()> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
107 let ret = unsafe { pam_ffi::pam_acct_mgmt(self.handle.0, flags.bits() as c_int) };
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
108 let result = ErrorCode::result_from(ret);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
109 self.last_return.set(result);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
110 result
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
111 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
112
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
113 fn change_authtok(&mut self, flags: Flags) -> Result<()> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
114 let ret = unsafe { pam_ffi::pam_chauthtok(self.handle.0, flags.bits() as c_int) };
97
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
115 let result = ErrorCode::result_from(ret);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
116 self.last_return.set(result);
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
117 result
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
118 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
119 }
efe2f5f8b5b2 Implement "stateless" application-side PAM calls.
Paul Fisher <paul@pfish.zone>
parents: 96
diff changeset
120
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
121 // TODO: pam_authenticate - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
122 // pam_setcred - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
123 // pam_acct_mgmt - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
124 // pam_chauthtok - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
125 // pam_open_session - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
126 // pam_close_session - app
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
127 // pam_putenv - shared
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
128 // pam_getenv - shared
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
129 // pam_getenvlist - shared
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
130
90
f6186e41399b Miscellaneous fixes and cleanup:
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
131 impl Drop for OwnedLibPamHandle<'_> {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
132 /// Closes the PAM session on an owned PAM handle.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
133 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
134 /// See the [`pam_end` manual page][man] for more information.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
135 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
136 /// [man]: https://www.man7.org/linux/man-pages/man3/pam_end.3.html
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
137 fn drop(&mut self) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
138 unsafe {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
139 pam_ffi::pam_end(
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
140 self.handle.0,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
141 ErrorCode::result_to_c(self.last_return.get()),
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
142 );
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
143 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
144 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
145 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
146
92
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
147 /// Macro to implement getting/setting a CStr-based item.
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
148 macro_rules! cstr_item {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
149 (get = $getter:ident, item = $item_type:path) => {
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
150 fn $getter(&self) -> Result<Option<String>> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
151 unsafe { self.get_cstr_item($item_type) }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
152 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
153 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
154 (set = $setter:ident, item = $item_type:path) => {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
155 fn $setter(&mut self, value: Option<&str>) -> Result<()> {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
156 unsafe { self.set_cstr_item($item_type, value) }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
157 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
158 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
159 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
160
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
161 impl PamShared for LibPamHandle {
92
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
162 fn log(&self, level: Level, entry: &str) {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
163 let entry = match CString::new(entry).or_else(|_| CString::new(dbg!(entry))) {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
164 Ok(cstr) => cstr,
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
165 _ => return,
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
166 };
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
167 #[cfg(pam_impl = "linux-pam")]
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
168 {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
169 // SAFETY: We're calling this function with a known value.
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
170 unsafe {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
171 pam_ffi::pam_syslog(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr())
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
172 }
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
173 }
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
174 #[cfg(pam_impl = "openpam")]
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
175 {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
176 // SAFETY: We're calling this function with a known value.
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
177 unsafe {
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
178 pam_ffi::openpam_log(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr())
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
179 }
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
180 }
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
181 }
5ddbcada30f2 Add the ability to log against a PAM handle.
Paul Fisher <paul@pfish.zone>
parents: 90
diff changeset
182
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
183 fn username(&mut self, prompt: Option<&str>) -> Result<String> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
184 let prompt = memory::option_cstr(prompt)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
185 let mut output: *const c_char = ptr::null();
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
186 let ret = unsafe {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
187 pam_ffi::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref()))
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
188 };
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
189 ErrorCode::result_from(ret)?;
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
190 unsafe { memory::copy_pam_string(output) }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
191 .transpose()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
192 .unwrap_or(Err(ErrorCode::ConversationError))
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
193 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
194
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
195 fn environ(&self) -> impl EnvironMap {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
196 LibPamEnviron::new(self)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
197 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
198
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
199 fn environ_mut(&mut self) -> impl EnvironMapMut {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
200 LibPamEnvironMut::new(self)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
201 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
202
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
203 cstr_item!(get = user_item, item = ItemType::User);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
204 cstr_item!(set = set_user_item, item = ItemType::User);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
205 cstr_item!(get = service, item = ItemType::Service);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
206 cstr_item!(set = set_service, item = ItemType::Service);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
207 cstr_item!(get = user_prompt, item = ItemType::UserPrompt);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
208 cstr_item!(set = set_user_prompt, item = ItemType::UserPrompt);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
209 cstr_item!(get = tty_name, item = ItemType::Tty);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
210 cstr_item!(set = set_tty_name, item = ItemType::Tty);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
211 cstr_item!(get = remote_user, item = ItemType::RemoteUser);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
212 cstr_item!(set = set_remote_user, item = ItemType::RemoteUser);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
213 cstr_item!(get = remote_host, item = ItemType::RemoteHost);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
214 cstr_item!(set = set_remote_host, item = ItemType::RemoteHost);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
215 cstr_item!(set = set_authtok_item, item = ItemType::AuthTok);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
216 cstr_item!(set = set_old_authtok_item, item = ItemType::OldAuthTok);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
217 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
218
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
219 impl Conversation for LibPamHandle {
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
220 fn communicate(&self, messages: &[Message]) {
77
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
221 match self.conversation_item() {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
222 Ok(conv) => conv.communicate(messages),
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
223 Err(e) => {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
224 for msg in messages {
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
225 msg.set_error(e)
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
226 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
227 }
351bdc13005e Update the libpam module to work with the new structure.
Paul Fisher <paul@pfish.zone>
parents: 75
diff changeset
228 }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
229 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
230 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
231
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
232 impl PamHandleModule for LibPamHandle {
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
233 fn authtok(&mut self, prompt: Option<&str>) -> Result<String> {
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
234 let prompt = memory::option_cstr(prompt)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
235 let mut output: *const c_char = ptr::null_mut();
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
236 // SAFETY: We're calling this with known-good values.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
237 let res = unsafe {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
238 pam_ffi::pam_get_authtok(
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
239 self,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
240 ItemType::AuthTok.into(),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
241 &mut output,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
242 memory::prompt_ptr(prompt.as_ref()),
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
243 )
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
244 };
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
245 ErrorCode::result_from(res)?;
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
246 // SAFETY: We got this string from PAM.
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
247 unsafe { memory::copy_pam_string(output) }
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
248 .transpose()
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
249 .unwrap_or(Err(ErrorCode::ConversationError))
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
250 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
251
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
252 cstr_item!(get = authtok_item, item = ItemType::AuthTok);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
253 cstr_item!(get = old_authtok_item, item = ItemType::OldAuthTok);
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
254 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
255
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
256 /// Function called at the end of a PAM session that is called to clean up
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
257 /// a value previously provided to PAM in a `pam_set_data` call.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
258 ///
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
259 /// You should never call this yourself.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
260 extern "C" fn set_data_cleanup<T>(_: *const libc::c_void, c_data: *mut libc::c_void, _: c_int) {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
261 unsafe {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
262 let _data: Box<T> = Box::from_raw(c_data.cast());
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
263 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
264 }
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
265
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
266 impl LibPamHandle {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
267 /// Gets a C string item.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
268 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
269 /// # Safety
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
270 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
271 /// You better be requesting an item which is a C string.
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
272 unsafe fn get_cstr_item(&self, item_type: ItemType) -> Result<Option<String>> {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
273 let mut output = ptr::null();
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
274 let ret = unsafe { pam_ffi::pam_get_item(self, item_type as c_int, &mut output) };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
275 ErrorCode::result_from(ret)?;
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
276 memory::copy_pam_string(output.cast())
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
277 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
278
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
279 /// Sets a C string item.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
280 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
281 /// # Safety
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
282 ///
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
283 /// You better be setting an item which is a C string.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
284 unsafe fn set_cstr_item(&mut self, item_type: ItemType, data: Option<&str>) -> Result<()> {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
285 let data_str = memory::option_cstr(data)?;
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
286 let ret = unsafe {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
287 pam_ffi::pam_set_item(
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
288 self,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
289 item_type as c_int,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
290 memory::prompt_ptr(data_str.as_ref()).cast(),
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
291 )
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
292 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
293 ErrorCode::result_from(ret)
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
294 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
295
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
296 /// Gets the `PAM_CONV` item from the handle.
96
f3e260f9ddcb Make conversation trait use immutable references.
Paul Fisher <paul@pfish.zone>
parents: 95
diff changeset
297 fn conversation_item(&self) -> Result<&mut LibPamConversation<'_>> {
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
298 let output: *mut LibPamConversation = ptr::null_mut();
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
299 let result = unsafe {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
300 pam_ffi::pam_get_item(
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
301 self,
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
302 ItemType::Conversation.into(),
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
303 &mut output.cast_const().cast(),
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
304 )
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
305 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
306 ErrorCode::result_from(result)?;
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
307 // SAFETY: We got this result from PAM, and we're checking if it's null.
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
308 unsafe { output.as_mut() }.ok_or(ErrorCode::ConversationError)
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
309 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
310 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
311
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
312 macro_rules! delegate {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
313 // First have the kind that save the result after delegation.
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
314 (fn $meth:ident(&self $(, $param:ident: $typ:ty)*) -> Result<$ret:ty>) => {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
315 fn $meth(&self $(, $param: $typ)*) -> Result<$ret> {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
316 let result = self.handle.$meth($($param),*);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
317 self.last_return.set(split(&result));
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
318 result
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
319 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
320 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
321 (fn $meth:ident(&mut self $(, $param:ident: $typ:ty)*) -> Result<$ret:ty>) => {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
322 fn $meth(&mut self $(, $param: $typ)*) -> Result<$ret> {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
323 let result = self.handle.$meth($($param),*);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
324 self.last_return.set(split(&result));
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
325 result
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
326 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
327 };
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
328 // Then have the kind that are just raw delegates
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
329 (fn $meth:ident(&self $(, $param:ident: $typ:ty)*) -> $ret:ty) => {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
330 fn $meth(&self $(, $param: $typ)*) -> $ret {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
331 self.handle.$meth($($param),*)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
332 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
333 };
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
334 (fn $meth:ident(&mut self $(, $param:ident: $typ:ty)*) -> $ret:ty) => {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
335 fn $meth(&mut self $(, $param: $typ)*) -> $ret {
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
336 self.handle.$meth($($param),*)
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
337 }
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
338 };
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
339 // Then have item getters / setters
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
340 (get = $get:ident$(, set = $set:ident)?) => {
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
341 delegate!(fn $get(&self) -> Result<Option<String>>);
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
342 $(delegate!(set = $set);)?
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
343 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
344 (set = $set:ident) => {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
345 delegate!(fn $set(&mut self, value: Option<&str>) -> Result<()>);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
346 };
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
347 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
348
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
349 fn split<T>(result: &Result<T>) -> Result<()> {
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
350 result.as_ref().map(drop).map_err(|&e| e)
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
351 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
352
90
f6186e41399b Miscellaneous fixes and cleanup:
Paul Fisher <paul@pfish.zone>
parents: 80
diff changeset
353 impl PamShared for OwnedLibPamHandle<'_> {
98
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
354 delegate!(fn log(&self, level: Level, entry: &str) -> ());
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
355 delegate!(fn environ(&self) -> impl EnvironMap);
b87100c5eed4 Start on environment variables, and make pointers nicer.
Paul Fisher <paul@pfish.zone>
parents: 97
diff changeset
356 delegate!(fn environ_mut(&mut self) -> impl EnvironMapMut);
95
51c9d7e8261a Return owned strings rather than borrowed strings.
Paul Fisher <paul@pfish.zone>
parents: 92
diff changeset
357 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<String>);
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
358 delegate!(get = user_item, set = set_user_item);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
359 delegate!(get = service, set = set_service);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
360 delegate!(get = user_prompt, set = set_user_prompt);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
361 delegate!(get = tty_name, set = set_tty_name);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
362 delegate!(get = remote_user, set = set_remote_user);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
363 delegate!(get = remote_host, set = set_remote_host);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
364 delegate!(set = set_authtok_item);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
365 delegate!(set = set_old_authtok_item);
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
366 }
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
367
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
368 /// Identifies what is being gotten or set with `pam_get_item`
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
369 /// or `pam_set_item`.
80
5aa1a010f1e8 Start using PAM headers; improve owned/borrowed distinction.
Paul Fisher <paul@pfish.zone>
parents: 78
diff changeset
370 #[derive(TryFromPrimitive, IntoPrimitive)]
73
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
371 #[repr(i32)]
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
372 #[non_exhaustive] // because C could give us anything!
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
373 pub enum ItemType {
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
374 /// The PAM service name.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
375 Service = 1,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
376 /// The user's login name.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
377 User = 2,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
378 /// The TTY name.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
379 Tty = 3,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
380 /// The remote host (if applicable).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
381 RemoteHost = 4,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
382 /// The conversation struct (not a CStr-based item).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
383 Conversation = 5,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
384 /// The authentication token (password).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
385 AuthTok = 6,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
386 /// The old authentication token (when changing passwords).
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
387 OldAuthTok = 7,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
388 /// The remote user's name.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
389 RemoteUser = 8,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
390 /// The prompt shown when requesting a username.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
391 UserPrompt = 9,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
392 /// App-supplied function to override failure delays.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
393 FailDelay = 10,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
394 /// X display name.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
395 XDisplay = 11,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
396 /// X server authentication data.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
397 XAuthData = 12,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
398 /// The type of `pam_get_authtok`.
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
399 AuthTokType = 13,
ac6881304c78 Do conversations, along with way too much stuff.
Paul Fisher <paul@pfish.zone>
parents:
diff changeset
400 }