diff --git a/libazureinit/src/provision/user.rs b/libazureinit/src/provision/user.rs index 4b9ee2b..1abd48f 100644 --- a/libazureinit/src/provision/user.rs +++ b/libazureinit/src/provision/user.rs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -use std::process::Command; +use std::{fs::Permissions, os::unix::fs::PermissionsExt, process::Command}; + +use std::io::Write; use tracing::instrument; @@ -88,11 +90,13 @@ pub enum Provisioner { impl Provisioner { pub(crate) fn create(&self, user: &User) -> Result<(), Error> { - match self { + let _ = match self { Self::Useradd => useradd(user), #[cfg(test)] Self::FakeUseradd => Ok(()), - } + }; + let path = "/etc/sudoers.d/azure-init-user"; + add_user_for_passwordless_sudo(user.name.clone(), path) } } @@ -123,10 +127,39 @@ fn useradd(user: &User) -> Result<(), Error> { Ok(()) } +fn add_user_for_passwordless_sudo( + username: String, + path: &str, +) -> Result<(), Error> { + // Create a file under /etc/sudoers.d with azure-init-user + let sudoers_path = path; + let mut sudoers_file = std::fs::OpenOptions::new() + .append(true) + .create(true) + .open(sudoers_path)?; + write!( + sudoers_file, + "{} ALL=(ALL) NOPASSWD: ALL \n", + username.to_string() + )?; + sudoers_file.flush()?; + // Set the permission + sudoers_file.set_permissions(Permissions::from_mode(0o600))?; + Ok(()) +} + #[cfg(test)] mod tests { + use std::{ + fs::{self, Permissions}, + os::unix::fs::PermissionsExt, + }; + use crate::User; + use super::add_user_for_passwordless_sudo; + const PATH: &str = "/tmp/test1"; + #[test] fn password_skipped_in_debug() { let user_with_password = @@ -142,4 +175,17 @@ mod tests { format!("{:?}", user_without_password) ); } + + #[test] + fn test_user_insecure() { + let user_insecure = User::new("azureuser", []); + let a = add_user_for_passwordless_sudo(user_insecure.name, PATH); + assert!(a.is_ok()); + assert!(fs::metadata(PATH).is_ok(), "Specified file not created"); + assert_eq!( + fs::Permissions(PATH).mode(), + Permissions.mode(0o600), + "Permissions are not set properly" + ); + } }