aquatic/aquatic_common/src/privileges.rs
Joakim Frostegård a208775104
Include documentation in printed config files (#41)
* Start work on printing toml config with comments

* WIP: toml_config: extract default values for fields

* WIP: toml_config: handle single-level nested structs

* WIP: toml_config: improve comment handling, std type trait impls

* WIP: toml_config: add Private trait, improve comment handling, clean up

* toml_config: fix default value bug; improve tests

* Use toml_config in all applicable crates; add toml_config enum support

* toml_config: improve comments

* toml_config_derive: support enum comments

* Improve config comments for udp, cli_helpers, common

* Improve config comments

* Add tests for Config struct TomlConfig implementations

* Improve Config comments

* Improve Config comments

* ws, http: add config comments for tls cert and private key lines

* small fixes to toml_config and toml_config_derive

* Run cargo fmt

* Fix typo in several config comments

* Update README

* Update README
2021-12-26 11:33:27 +01:00

65 lines
1.5 KiB
Rust

use std::{
sync::{
atomic::{AtomicUsize, Ordering},
Arc,
},
time::Duration,
};
use privdrop::PrivDrop;
use serde::Deserialize;
use toml_config::TomlConfig;
#[derive(Clone, Debug, PartialEq, TomlConfig, Deserialize)]
#[serde(default)]
pub struct PrivilegeConfig {
/// Chroot and switch user after binding to sockets
pub drop_privileges: bool,
/// Chroot to this path
pub chroot_path: String,
/// User to switch to after chrooting
pub user: String,
}
impl Default for PrivilegeConfig {
fn default() -> Self {
Self {
drop_privileges: false,
chroot_path: ".".to_string(),
user: "nobody".to_string(),
}
}
}
pub fn drop_privileges_after_socket_binding(
config: &PrivilegeConfig,
num_bound_sockets: Arc<AtomicUsize>,
target_num: usize,
) -> anyhow::Result<()> {
if config.drop_privileges {
let mut counter = 0usize;
loop {
let num_bound = num_bound_sockets.load(Ordering::SeqCst);
if num_bound == target_num {
PrivDrop::default()
.chroot(config.chroot_path.clone())
.user(config.user.clone())
.apply()?;
break;
}
::std::thread::sleep(Duration::from_millis(10));
counter += 1;
if counter == 500 {
panic!("Sockets didn't bind in time for privilege drop.");
}
}
}
Ok(())
}