Make compile-time feature for SUID/SGID mode
This commit is contained in:
@@ -19,12 +19,14 @@ use crate::{
|
||||
/// If neither is feasible, an error is returned.
|
||||
fn will_connect_to_external_server(
|
||||
server_socket_path: Option<&PathBuf>,
|
||||
config_path: Option<&PathBuf>,
|
||||
// This parameter is only used in suid-sgid-mode
|
||||
#[allow(unused_variables)] config_path: Option<&PathBuf>,
|
||||
) -> anyhow::Result<bool> {
|
||||
if server_socket_path.is_some() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
#[cfg(feature = "suid-sgid-mode")]
|
||||
if config_path.is_some() {
|
||||
return Ok(false);
|
||||
}
|
||||
@@ -33,11 +35,16 @@ fn will_connect_to_external_server(
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
#[cfg(feature = "suid-sgid-mode")]
|
||||
if fs::metadata(DEFAULT_CONFIG_PATH).is_ok() {
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
#[cfg(feature = "suid-sgid-mode")]
|
||||
anyhow::bail!("No socket path or config path provided, and no default socket or config found");
|
||||
|
||||
#[cfg(not(feature = "suid-sgid-mode"))]
|
||||
anyhow::bail!("No socket path provided, and no default socket found");
|
||||
}
|
||||
|
||||
/// This function is used to bootstrap the connection to the server.
|
||||
@@ -77,7 +84,7 @@ pub fn bootstrap_server_connection_and_drop_privileges(
|
||||
.init();
|
||||
|
||||
connect_to_external_server(server_socket_path)
|
||||
} else {
|
||||
} else if cfg!(feature = "suid-sgid-mode") {
|
||||
// NOTE: We need to be really careful with the code up until this point,
|
||||
// as we might be running with elevated privileges.
|
||||
let server_connection = bootstrap_internal_server_and_drop_privs(config)?;
|
||||
@@ -87,6 +94,8 @@ pub fn bootstrap_server_connection_and_drop_privileges(
|
||||
.init();
|
||||
|
||||
Ok(server_connection)
|
||||
} else {
|
||||
anyhow::bail!("SUID/SGID support is not enabled, cannot start internal server");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use anyhow::Context;
|
||||
use nix::unistd::{Group as LibcGroup, User as LibcUser};
|
||||
use std::{fs, os::unix::fs::PermissionsExt};
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
use std::ffi::CString;
|
||||
@@ -21,23 +20,6 @@ fn get_unix_groups(_user: &LibcUser) -> anyhow::Result<Vec<LibcGroup>> {
|
||||
Ok(vec![])
|
||||
}
|
||||
|
||||
/// Check if the current executable is SUID or SGID.
|
||||
///
|
||||
/// If the check fails, an error is returned.
|
||||
pub fn executable_is_suid_or_sgid() -> anyhow::Result<bool> {
|
||||
let result = std::env::current_exe()
|
||||
.context("Failed to get current executable path")
|
||||
.and_then(|executable| {
|
||||
fs::metadata(executable).context("Failed to get executable metadata")
|
||||
})
|
||||
.context("Failed to check SUID/SGID bits on executable")
|
||||
.map(|metadata| {
|
||||
let mode = metadata.permissions().mode();
|
||||
mode & 0o4000 != 0 || mode & 0o2000 != 0
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
fn get_unix_groups(user: &LibcUser) -> anyhow::Result<Vec<LibcGroup>> {
|
||||
let user_cstr =
|
||||
@@ -61,6 +43,31 @@ fn get_unix_groups(user: &LibcUser) -> anyhow::Result<Vec<LibcGroup>> {
|
||||
Ok(groups)
|
||||
}
|
||||
|
||||
/// Check if the current executable is SUID or SGID.
|
||||
///
|
||||
/// If the check fails, an error is returned.
|
||||
#[cfg(feature = "suid-sgid-mode")]
|
||||
pub fn executable_is_suid_or_sgid() -> anyhow::Result<bool> {
|
||||
use std::{fs, os::unix::fs::PermissionsExt};
|
||||
let result = std::env::current_exe()
|
||||
.context("Failed to get current executable path")
|
||||
.and_then(|executable| {
|
||||
fs::metadata(executable).context("Failed to get executable metadata")
|
||||
})
|
||||
.context("Failed to check SUID/SGID bits on executable")
|
||||
.map(|metadata| {
|
||||
let mode = metadata.permissions().mode();
|
||||
mode & 0o4000 != 0 || mode & 0o2000 != 0
|
||||
})?;
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "suid-sgid-mode"))]
|
||||
#[inline]
|
||||
pub fn executable_is_suid_or_sgid() -> anyhow::Result<bool> {
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
impl UnixUser {
|
||||
pub fn from_uid(uid: u32) -> anyhow::Result<Self> {
|
||||
let libc_uid = nix::unistd::Uid::from_raw(uid);
|
||||
|
||||
Reference in New Issue
Block a user