From 38cf1d6e980d1124b7f6fe7dacee1745ae403a1a Mon Sep 17 00:00:00 2001 From: Adrian Heine Date: Tue, 28 Feb 2017 21:59:16 +0100 Subject: [PATCH] Sort out running as a user --- Cargo.toml | 3 +++ src/command_runner.rs | 16 +++++++++++++--- src/lib.rs | 2 ++ src/symbols/nginx/server.rs | 6 +++--- src/symbols/systemd/node_js_user_service.rs | 20 ++++++++++++-------- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 15ba454..fa16817 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,5 +3,8 @@ name = "schematics" version = "0.1.0" authors = ["Adrian Heine "] +[dependencies] +users = "0.5.0" + [dev-dependencies] tempdir = "0.3" diff --git a/src/command_runner.rs b/src/command_runner.rs index 52ac7ce..e82bba6 100644 --- a/src/command_runner.rs +++ b/src/command_runner.rs @@ -34,11 +34,21 @@ impl<'a, C> UserCommandRunner<'a, C> where C: 'a + CommandRunner { } } +use std::os::unix::process::CommandExt; +use std::env; +use users::get_user_by_name; + impl<'a, C> CommandRunner for UserCommandRunner<'a, C> where C: 'a + CommandRunner { fn run_with_args(&self, program: &str, args: &[&str]) -> IoResult { - let mut new_args = vec![self.user_name, "-s", "/usr/bin/env", "--", program]; - new_args.extend_from_slice(args); - self.command_runner.run_with_args("su", &new_args) + let uid = get_user_by_name(self.user_name).unwrap().uid(); + let old_home = env::var("HOME"); + env::set_var("HOME", format!("/home/{}", self.user_name)); + let old_dbus = env::var("DBUS_SESSION_BUS_ADDRESS"); + env::set_var("DBUS_SESSION_BUS_ADDRESS", format!("unix:path=/run/user/{}/bus", uid)); + let res = Command::new(program).uid(uid).gid(uid).args(args).output(); + if let Ok(dbus) = old_dbus { env::set_var("DBUS_SESSION_BUS_ADDRESS", dbus); } + if let Ok(home) = old_home { env::set_var("HOME", home); } + res } } diff --git a/src/lib.rs b/src/lib.rs index 21d86c1..58bbdc8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,6 +20,8 @@ missing_debug_implementations #![allow(box_pointers)] +extern crate users; + pub mod command_runner; pub mod loggers; pub mod symbols; diff --git a/src/symbols/nginx/server.rs b/src/symbols/nginx/server.rs index 3fcf786..739f018 100644 --- a/src/symbols/nginx/server.rs +++ b/src/symbols/nginx/server.rs @@ -49,7 +49,7 @@ pub struct NginxServer<'a, C> where C: Deref { use std::borrow::Cow; impl<'a> NginxServer<'a, String> { - pub fn new(home: &'a str, domain: &'a str, static_path: &'a str, redir_domains: &[&'a str], command_runner: &'a CommandRunner) -> Self { + pub fn new(socket_path: &'a str, domain: &'a str, static_path: &'a str, redir_domains: &[&'a str], command_runner: &'a CommandRunner) -> Self { let file_path: Cow = Cow::from(String::from("/etc/nginx/sites-enabled/") + domain); let redir_content = redir_domains.iter().map(|redir_domain| format!("server {{ @@ -75,10 +75,10 @@ impl<'a> NginxServer<'a, String> { location @proxy {{ include fastcgi_params; - proxy_pass http://unix:{}/var/service.socket:; + proxy_pass http://unix:{}:; proxy_redirect off; }} -}}", domain, static_path, home); +}}", domain, static_path, socket_path); NginxServer { command_runner: command_runner, file: FileSymbol::new(file_path, content) diff --git a/src/symbols/systemd/node_js_user_service.rs b/src/symbols/systemd/node_js_user_service.rs index 941cfbe..53b2740 100644 --- a/src/symbols/systemd/node_js_user_service.rs +++ b/src/symbols/systemd/node_js_user_service.rs @@ -56,6 +56,7 @@ impl fmt::Display for NodeJsSystemdUserServiceError { pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref { name: &'a str, home: &'a str, + uid: u32, path: P, command_runner: &'a CommandRunner, file: FileSymbol> @@ -64,20 +65,24 @@ pub struct NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display use std::borrow::Cow; impl<'a> NodeJsSystemdUserService<'a, Cow<'a, str>, String> { - pub fn new(home: &'a str, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self { + pub fn new(home: &'a str, uid: u32, name: &'a str, path: &'a str, command_runner: &'a CommandRunner) -> Self { let file_path: Cow = Cow::from(String::from(home.trim_right()) + "/.config/systemd/user/" + name + ".service"); let content = format!("[Service] -ExecStart=/usr/bin/nodejs {} +ExecStartPre=rm /var/tmp/{1}-{2}.socket +ExecStart=/usr/bin/nodejs {0} Restart=always Environment=NODE_ENV=production -Environment=PORT={}/var/service.socket +Environment=PORT=/var/tmp/{1}-{2}.socket +#RuntimeDirectory=service +#RuntimeDirectoryMode=766 [Install] WantedBy=default.target -", path, home); +", path, uid, name); NodeJsSystemdUserService { name: name, + uid: uid, home: home, path: file_path.clone(), command_runner: command_runner, @@ -121,9 +126,6 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef } fn execute(&self) -> Result<(), Box> { - try!(self.command_runner.run_with_args("mkdir", &["-p", &format!("{}/var", self.home)])); - try!(self.command_runner.run_with_args("rm", &[&format!("{}/var/service.socket", self.home)])); - try!(self.command_runner.run_with_args("mkdir", &["-p", Path::new(self.path.as_ref()).parent().unwrap().to_str().unwrap()])); // FIXME: Permissions // try!(create_dir_all(Path::new(&path).parent().unwrap())); @@ -136,7 +138,7 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef if !(try!(self.check_if_service())) { return Err(Box::new(NodeJsSystemdUserServiceError::GenericError as NodeJsSystemdUserServiceError)); } - let file_name = format!("{}/var/service.socket", self.home); + let file_name = format!("/var/tmp/{}-{}.socket", self.uid, self.name); // try!(self.command_runner.run_with_args("chmod", &["666", &file_name])); sleep(Duration::from_millis(500)); @@ -148,9 +150,11 @@ impl<'a, P, C> Symbol for NodeJsSystemdUserService<'a, P, C> where P: AsRef Ok(()) } +/* // FIXME fn get_prerequisites(&self) -> Vec> { self.file.get_prerequisites() } +*/ } impl<'a, P, C> fmt::Display for NodeJsSystemdUserService<'a, P, C> where P: AsRef + fmt::Display, C: Deref {