Mercurial > crates > nonstick
comparison src/libpam/handle.rs @ 95:51c9d7e8261a
Return owned strings rather than borrowed strings.
It's going to be irritating to have to work with strings borrowed from the
PAM handle rather than just using your own. They're cheap enough to copy.
author | Paul Fisher <paul@pfish.zone> |
---|---|
date | Mon, 23 Jun 2025 14:03:44 -0400 |
parents | 5ddbcada30f2 |
children | f3e260f9ddcb |
comparison
equal
deleted
inserted
replaced
94:db167f96ba46 | 95:51c9d7e8261a |
---|---|
63 } | 63 } |
64 | 64 |
65 /// Macro to implement getting/setting a CStr-based item. | 65 /// Macro to implement getting/setting a CStr-based item. |
66 macro_rules! cstr_item { | 66 macro_rules! cstr_item { |
67 (get = $getter:ident, item = $item_type:path) => { | 67 (get = $getter:ident, item = $item_type:path) => { |
68 fn $getter(&self) -> Result<Option<&str>> { | 68 fn $getter(&self) -> Result<Option<String>> { |
69 unsafe { self.get_cstr_item($item_type) } | 69 unsafe { self.get_cstr_item($item_type) } |
70 } | 70 } |
71 }; | 71 }; |
72 (set = $setter:ident, item = $item_type:path) => { | 72 (set = $setter:ident, item = $item_type:path) => { |
73 fn $setter(&mut self, value: Option<&str>) -> Result<()> { | 73 fn $setter(&mut self, value: Option<&str>) -> Result<()> { |
96 pam_ffi::openpam_log(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr()) | 96 pam_ffi::openpam_log(self, level as c_int, c"%s".as_ptr().cast(), entry.as_ptr()) |
97 } | 97 } |
98 } | 98 } |
99 } | 99 } |
100 | 100 |
101 fn username(&mut self, prompt: Option<&str>) -> Result<&str> { | 101 fn username(&mut self, prompt: Option<&str>) -> Result<String> { |
102 let prompt = memory::option_cstr(prompt)?; | 102 let prompt = memory::option_cstr(prompt)?; |
103 let mut output: *const c_char = ptr::null(); | 103 let mut output: *const c_char = ptr::null(); |
104 let ret = unsafe { | 104 let ret = unsafe { |
105 pam_ffi::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref())) | 105 pam_ffi::pam_get_user(self, &mut output, memory::prompt_ptr(prompt.as_ref())) |
106 }; | 106 }; |
107 ErrorCode::result_from(ret)?; | 107 ErrorCode::result_from(ret)?; |
108 unsafe { memory::wrap_string(output) } | 108 unsafe { memory::copy_pam_string(output) } |
109 .transpose() | 109 .transpose() |
110 .unwrap_or(Err(ErrorCode::ConversationError)) | 110 .unwrap_or(Err(ErrorCode::ConversationError)) |
111 } | 111 } |
112 | 112 |
113 cstr_item!(get = user_item, item = ItemType::User); | 113 cstr_item!(get = user_item, item = ItemType::User); |
138 } | 138 } |
139 } | 139 } |
140 } | 140 } |
141 | 141 |
142 impl PamHandleModule for LibPamHandle { | 142 impl PamHandleModule for LibPamHandle { |
143 fn authtok(&mut self, prompt: Option<&str>) -> Result<&str> { | 143 fn authtok(&mut self, prompt: Option<&str>) -> Result<String> { |
144 let prompt = memory::option_cstr(prompt)?; | 144 let prompt = memory::option_cstr(prompt)?; |
145 let mut output: *const c_char = ptr::null_mut(); | 145 let mut output: *const c_char = ptr::null_mut(); |
146 // SAFETY: We're calling this with known-good values. | 146 // SAFETY: We're calling this with known-good values. |
147 let res = unsafe { | 147 let res = unsafe { |
148 pam_ffi::pam_get_authtok( | 148 pam_ffi::pam_get_authtok( |
152 memory::prompt_ptr(prompt.as_ref()), | 152 memory::prompt_ptr(prompt.as_ref()), |
153 ) | 153 ) |
154 }; | 154 }; |
155 ErrorCode::result_from(res)?; | 155 ErrorCode::result_from(res)?; |
156 // SAFETY: We got this string from PAM. | 156 // SAFETY: We got this string from PAM. |
157 unsafe { memory::wrap_string(output) } | 157 unsafe { memory::copy_pam_string(output) } |
158 .transpose() | 158 .transpose() |
159 .unwrap_or(Err(ErrorCode::ConversationError)) | 159 .unwrap_or(Err(ErrorCode::ConversationError)) |
160 } | 160 } |
161 | 161 |
162 cstr_item!(get = authtok_item, item = ItemType::AuthTok); | 162 cstr_item!(get = authtok_item, item = ItemType::AuthTok); |
177 /// Gets a C string item. | 177 /// Gets a C string item. |
178 /// | 178 /// |
179 /// # Safety | 179 /// # Safety |
180 /// | 180 /// |
181 /// You better be requesting an item which is a C string. | 181 /// You better be requesting an item which is a C string. |
182 unsafe fn get_cstr_item(&self, item_type: ItemType) -> Result<Option<&str>> { | 182 unsafe fn get_cstr_item(&self, item_type: ItemType) -> Result<Option<String>> { |
183 let mut output = ptr::null(); | 183 let mut output = ptr::null(); |
184 let ret = unsafe { pam_ffi::pam_get_item(self, item_type as c_int, &mut output) }; | 184 let ret = unsafe { pam_ffi::pam_get_item(self, item_type as c_int, &mut output) }; |
185 ErrorCode::result_from(ret)?; | 185 ErrorCode::result_from(ret)?; |
186 memory::wrap_string(output.cast()) | 186 memory::copy_pam_string(output.cast()) |
187 } | 187 } |
188 | 188 |
189 /// Sets a C string item. | 189 /// Sets a C string item. |
190 /// | 190 /// |
191 /// # Safety | 191 /// # Safety |
233 self.last_return.set(split(&result)); | 233 self.last_return.set(split(&result)); |
234 result | 234 result |
235 } | 235 } |
236 }; | 236 }; |
237 (get = $get:ident$(, set = $set:ident)?) => { | 237 (get = $get:ident$(, set = $set:ident)?) => { |
238 delegate!(fn $get(&self) -> Result<Option<&str>>); | 238 delegate!(fn $get(&self) -> Result<Option<String>>); |
239 $(delegate!(set = $set);)? | 239 $(delegate!(set = $set);)? |
240 }; | 240 }; |
241 (set = $set:ident) => { | 241 (set = $set:ident) => { |
242 delegate!(fn $set(&mut self, value: Option<&str>) -> Result<()>); | 242 delegate!(fn $set(&mut self, value: Option<&str>) -> Result<()>); |
243 }; | 243 }; |
249 | 249 |
250 impl PamShared for OwnedLibPamHandle<'_> { | 250 impl PamShared for OwnedLibPamHandle<'_> { |
251 fn log(&self, level: Level, entry: &str) { | 251 fn log(&self, level: Level, entry: &str) { |
252 self.handle.log(level, entry) | 252 self.handle.log(level, entry) |
253 } | 253 } |
254 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<&str>); | 254 delegate!(fn username(&mut self, prompt: Option<&str>) -> Result<String>); |
255 delegate!(get = user_item, set = set_user_item); | 255 delegate!(get = user_item, set = set_user_item); |
256 delegate!(get = service, set = set_service); | 256 delegate!(get = service, set = set_service); |
257 delegate!(get = user_prompt, set = set_user_prompt); | 257 delegate!(get = user_prompt, set = set_user_prompt); |
258 delegate!(get = tty_name, set = set_tty_name); | 258 delegate!(get = tty_name, set = set_tty_name); |
259 delegate!(get = remote_user, set = set_remote_user); | 259 delegate!(get = remote_user, set = set_remote_user); |