diff --git a/src/service/local.rs b/src/service/local.rs index 6bfdd154191d..e3b4dea740ba 100644 --- a/src/service/local.rs +++ b/src/service/local.rs @@ -17,12 +17,7 @@ use shadowsocks_service::shadowsocks::relay::socks5::Address; use shadowsocks_service::{ acl::AccessControl, config::{ - read_variable_field_value, - Config, - ConfigType, - LocalConfig, - LocalInstanceConfig, - ProtocolType, + read_variable_field_value, Config, ConfigType, LocalConfig, LocalInstanceConfig, ProtocolType, ServerInstanceConfig, }, local::{loadbalancing::PingBalancer, Server}, @@ -37,8 +32,7 @@ use shadowsocks_service::{ use crate::logging; use crate::{ config::{Config as ServiceConfig, RuntimeMode}, - monitor, - vparser, + monitor, vparser, }; #[cfg(feature = "local-dns")] @@ -850,7 +844,10 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future("USER") { - crate::sys::run_as_user(uname); + if let Err(err) = crate::sys::run_as_user(uname) { + eprintln!("failed to change as user, error: {err}"); + return Err(crate::EXIT_CODE_INSUFFICIENT_PARAMS.into()); + } } info!("shadowsocks local {} build {}", crate::VERSION, crate::BUILD_TIME); diff --git a/src/service/manager.rs b/src/service/manager.rs index 0ec8e3d655ee..4039577da8ba 100644 --- a/src/service/manager.rs +++ b/src/service/manager.rs @@ -27,8 +27,7 @@ use shadowsocks_service::{ use crate::logging; use crate::{ config::{Config as ServiceConfig, RuntimeMode}, - monitor, - vparser, + monitor, vparser, }; /// Defines command line options @@ -478,7 +477,10 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future("USER") { - crate::sys::run_as_user(uname); + if let Err(err) = crate::sys::run_as_user(uname) { + eprintln!("failed to change as user, error: {err}"); + return Err(crate::EXIT_CODE_INSUFFICIENT_PARAMS.into()); + } } info!("shadowsocks manager {} build {}", crate::VERSION, crate::BUILD_TIME); diff --git a/src/service/server.rs b/src/service/server.rs index 27505eb8e0c7..9d30fbfc32bb 100644 --- a/src/service/server.rs +++ b/src/service/server.rs @@ -25,8 +25,7 @@ use shadowsocks_service::{ use crate::logging; use crate::{ config::{Config as ServiceConfig, RuntimeMode}, - monitor, - vparser, + monitor, vparser, }; /// Defines command line options @@ -498,7 +497,10 @@ pub fn create(matches: &ArgMatches) -> Result<(Runtime, impl Future("USER") { - crate::sys::run_as_user(uname); + if let Err(err) = crate::sys::run_as_user(uname) { + eprintln!("failed to change as user, error: {err}"); + return Err(crate::EXIT_CODE_INSUFFICIENT_PARAMS.into()); + } } info!("shadowsocks server {} build {}", crate::VERSION, crate::BUILD_TIME); diff --git a/src/sys.rs b/src/sys.rs index cebd86031b2b..dc9501eba3a4 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -77,11 +77,11 @@ pub fn adjust_nofile() { /// setuid(), setgid() for a specific user or uid #[cfg(unix)] -pub fn run_as_user(uname: &str) { - use log::warn; +pub fn run_as_user(uname: &str) -> std::io::Result<()> { + use log::error; use std::{ ffi::{CStr, CString}, - io::Error, + io::{Error, ErrorKind}, }; unsafe { @@ -101,8 +101,7 @@ pub fn run_as_user(uname: &str) { }; if pwd.is_null() { - warn!("user {} not found", uname); - return; + return Err(Error::new(ErrorKind::InvalidInput, format!("user {} not found", uname))); } let pwd = &*pwd; @@ -111,37 +110,40 @@ pub fn run_as_user(uname: &str) { if libc::setgid(pwd.pw_gid as libc::gid_t) != 0 { let err = Error::last_os_error(); - warn!( + error!( "could not change group id to user {:?}'s gid: {}, uid: {}, error: {}", CStr::from_ptr(pwd.pw_name), pwd.pw_gid, pwd.pw_uid, err ); - return; + return Err(err); } if libc::initgroups(pwd.pw_name, pwd.pw_gid.try_into().unwrap()) != 0 { let err = Error::last_os_error(); - warn!( + error!( "could not change supplementary groups to user {:?}'s gid: {}, uid: {}, error: {}", CStr::from_ptr(pwd.pw_name), pwd.pw_gid, pwd.pw_uid, err ); - return; + return Err(err); } if libc::setuid(pwd.pw_uid) != 0 { let err = Error::last_os_error(); - warn!( + error!( "could not change user id to user {:?}'s gid: {}, uid: {}, error: {}", CStr::from_ptr(pwd.pw_name), pwd.pw_gid, pwd.pw_uid, err ); + return Err(err); } } + + Ok(()) }