1use std::process::Stdio;23use anyhow::{anyhow, bail};4use nix::unistd::User;5use remowt_polkit_shared::Identity;6use remowt_ui_prompt::Prompter;7use tokio::io::AsyncWriteExt as _;8use tokio::process::Command;910use super::protocol::run_conversation;11use super::Helper;1213#[derive(Clone)]14pub struct SuidHelper;15impl Helper for SuidHelper {16 async fn help_me<P: Prompter + 'static>(17 &self,18 cookie: &str,19 prompt: P,20 identity: Identity,21 ) -> anyhow::Result<()> {22 let Some(uid) = identity.uid() else {23 bail!("can't process identity");24 };25 let user = User::from_uid(uid)26 .map_err(|e| anyhow!("error querying user: {e}"))?27 .ok_or_else(|| anyhow!("user not found"))?;2829 let mut cmd = Command::new("polkit-agent-helper-1");30 cmd.arg(user.name);31 cmd.stdin(Stdio::piped());32 cmd.stdout(Stdio::piped());33 cmd.kill_on_drop(true);34 let mut child = cmd.spawn()?;35 let mut stdin = child.stdin.take().expect("piped");36 let stdout = child.stdout.take().expect("piped");3738 assert!(!cookie.contains('\n'));39 stdin.write_all(cookie.as_bytes()).await?;40 stdin.write_all(b"\n").await?;4142 let res = run_conversation(stdout, stdin, prompt).await;43 drop(child);44 res45 }46}