mirror of
https://github.com/fosrl/newt.git
synced 2026-03-04 09:46:44 +00:00
Allow sudo passwordless
This commit is contained in:
@@ -158,10 +158,51 @@ func createUser(username string, meta ConnectionMetadata) error {
|
|||||||
} else {
|
} else {
|
||||||
logger.Info("auth-daemon: added %s to %s", username, group)
|
logger.Info("auth-daemon: added %s to %s", username, group)
|
||||||
}
|
}
|
||||||
|
if err := configurePasswordlessSudo(username); err != nil {
|
||||||
|
logger.Warn("auth-daemon: configure passwordless sudo for %s: %v", username, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// configurePasswordlessSudo creates a sudoers.d file to allow passwordless sudo for the user
|
||||||
|
func configurePasswordlessSudo(username string) error {
|
||||||
|
sudoersFile := filepath.Join("/etc/sudoers.d", fmt.Sprintf("90-pangolin-%s", username))
|
||||||
|
content := fmt.Sprintf("# Created by newt auth-daemon\n%s ALL=(ALL) NOPASSWD:ALL\n", username)
|
||||||
|
|
||||||
|
// Write to temp file first
|
||||||
|
tmpFile := sudoersFile + ".tmp"
|
||||||
|
if err := os.WriteFile(tmpFile, []byte(content), 0440); err != nil {
|
||||||
|
return fmt.Errorf("write temp sudoers file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate with visudo
|
||||||
|
cmd := exec.Command("visudo", "-c", "-f", tmpFile)
|
||||||
|
if out, err := cmd.CombinedOutput(); err != nil {
|
||||||
|
os.Remove(tmpFile)
|
||||||
|
return fmt.Errorf("visudo validation failed: %w (output: %s)", err, string(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to final location
|
||||||
|
if err := os.Rename(tmpFile, sudoersFile); err != nil {
|
||||||
|
os.Remove(tmpFile)
|
||||||
|
return fmt.Errorf("move sudoers file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("auth-daemon: configured passwordless sudo for %s", username)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// removePasswordlessSudo removes the sudoers.d file for the user
|
||||||
|
func removePasswordlessSudo(username string) {
|
||||||
|
sudoersFile := filepath.Join("/etc/sudoers.d", fmt.Sprintf("90-newt-%s", username))
|
||||||
|
if err := os.Remove(sudoersFile); err != nil && !os.IsNotExist(err) {
|
||||||
|
logger.Warn("auth-daemon: remove passwordless sudo for %s: %v", username, err)
|
||||||
|
} else if err == nil {
|
||||||
|
logger.Info("auth-daemon: removed passwordless sudo for %s", username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func mustAtoi(s string) int {
|
func mustAtoi(s string) int {
|
||||||
n, _ := strconv.Atoi(s)
|
n, _ := strconv.Atoi(s)
|
||||||
return n
|
return n
|
||||||
@@ -189,6 +230,15 @@ func reconcileUser(u *user.User, meta ConnectionMetadata) error {
|
|||||||
logger.Info("auth-daemon: removed %s from %s", u.Username, group)
|
logger.Info("auth-daemon: removed %s from %s", u.Username, group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure passwordless sudo
|
||||||
|
if meta.Sudo {
|
||||||
|
if err := configurePasswordlessSudo(u.Username); err != nil {
|
||||||
|
logger.Warn("auth-daemon: configure passwordless sudo for %s: %v", u.Username, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removePasswordlessSudo(u.Username)
|
||||||
|
}
|
||||||
if meta.Homedir && u.HomeDir != "" {
|
if meta.Homedir && u.HomeDir != "" {
|
||||||
if st, err := os.Stat(u.HomeDir); err != nil || !st.IsDir() {
|
if st, err := os.Stat(u.HomeDir); err != nil || !st.IsDir() {
|
||||||
if err := os.MkdirAll(u.HomeDir, 0755); err != nil {
|
if err := os.MkdirAll(u.HomeDir, 0755); err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user