mirror of
https://github.com/ilya-zlobintsev/LACT.git
synced 2026-11-05 21:56:43 -06:00
* chore: bump rust edition to 2024 * chore: another chunk of clippy fixes * chore: fix warning in bindings * chore: restructure awkward unsafe blocks * chore: reformat * chore: clippy fix * chore: bump rust release in docker build
109 lines
2.9 KiB
Rust
109 lines
2.9 KiB
Rust
use anyhow::{Context, anyhow};
|
|
use nix::{
|
|
sys::stat::{Mode, umask},
|
|
unistd::{Gid, Group, User, chown, getuid},
|
|
};
|
|
use std::{
|
|
env, fs,
|
|
path::{Path, PathBuf},
|
|
str::FromStr,
|
|
};
|
|
use tokio::net::UnixListener;
|
|
use tracing::{debug, info};
|
|
|
|
use crate::{
|
|
config,
|
|
system::{IS_FLATBOX, run_command},
|
|
};
|
|
|
|
pub fn get_socket_path() -> PathBuf {
|
|
let uid = getuid();
|
|
|
|
if let Ok(path) = env::var("LACT_DAEMON_SOCKET_PATH") {
|
|
PathBuf::from_str(&path).unwrap()
|
|
} else if uid.is_root() {
|
|
PathBuf::from_str("/run/lactd.sock").unwrap()
|
|
} else {
|
|
PathBuf::from_str(&format!("/run/user/{uid}/lactd.sock")).unwrap()
|
|
}
|
|
}
|
|
|
|
pub fn cleanup() {
|
|
let socket_path = get_socket_path();
|
|
|
|
if socket_path.exists() {
|
|
fs::remove_file(socket_path).expect("failed to remove socket");
|
|
}
|
|
debug!("removed socket");
|
|
}
|
|
|
|
pub fn listen() -> anyhow::Result<(UnixListener, PathBuf)> {
|
|
let socket_path = get_socket_path();
|
|
|
|
if socket_path.exists() {
|
|
return Err(anyhow!(
|
|
"Socket {} already exists. \
|
|
This probably means that another instance of lact-daemon is currently running. \
|
|
If you are sure that this is not the case, please remove the file",
|
|
socket_path.display()
|
|
));
|
|
}
|
|
|
|
let socket_mask = Mode::S_IXUSR | Mode::S_IXGRP | Mode::S_IRWXO;
|
|
umask(socket_mask);
|
|
|
|
let listener = UnixListener::bind(&socket_path)?;
|
|
|
|
info!("listening on {socket_path:?}");
|
|
Ok((listener, socket_path))
|
|
}
|
|
|
|
pub async fn set_permissions(
|
|
socket_path: &Path,
|
|
daemon_config: &config::Daemon,
|
|
) -> anyhow::Result<()> {
|
|
let group = daemon_config
|
|
.admin_group
|
|
.as_ref()
|
|
.map(|name| {
|
|
Group::from_name(name)
|
|
.context("Could not get group")?
|
|
.with_context(|| format!("Group {name} does not exist"))
|
|
})
|
|
.transpose()?
|
|
.map_or_else(Gid::current, |group| group.gid);
|
|
|
|
let user = daemon_config
|
|
.admin_user
|
|
.as_ref()
|
|
.map(|name| {
|
|
User::from_name(name)
|
|
.context("Could not get group")?
|
|
.with_context(|| format!("Group {name} does not exist"))
|
|
})
|
|
.transpose()?
|
|
.map(|user| user.uid);
|
|
|
|
debug!("using gid {group} uid {user:?} for socket");
|
|
|
|
if *IS_FLATBOX {
|
|
let owner_arg = match user {
|
|
Some(user) => format!("{}:{}", user.as_raw(), group.as_raw()),
|
|
None => format!(":{}", group.as_raw()),
|
|
};
|
|
|
|
let path = socket_path
|
|
.to_str()
|
|
.expect("Invalid socket path")
|
|
.trim_start_matches("/run/host/root");
|
|
|
|
run_command("chown", &[&owner_arg, path])
|
|
.await
|
|
.context("Could not set socket permissions")?;
|
|
} else {
|
|
chown(socket_path, user, Some(group)).context("Could not set socket permissions")?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|