348 lines
9.8 KiB
Go
348 lines
9.8 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"host_service/utils"
|
|
"io"
|
|
"log"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
const SOCKET_PATH = "/var/run/usermgmt.sock"
|
|
|
|
type Command struct {
|
|
Action string `json:"action"`
|
|
Params map[string]interface{} `json:"params"`
|
|
}
|
|
|
|
type Response struct {
|
|
Success bool `json:"success"`
|
|
Data interface{} `json:"data"`
|
|
Error string `json:"error,omitempty"`
|
|
}
|
|
|
|
func main() {
|
|
// Ensure socket file does not exist
|
|
if err := exec.Command("rm", "-f", SOCKET_PATH).Run(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
listener, err := net.Listen("unix", SOCKET_PATH)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
defer listener.Close()
|
|
|
|
// Change socket permissions to allow Docker container access
|
|
if err := exec.Command("chmod", "777", SOCKET_PATH).Run(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
log.Printf("Listening on %s", SOCKET_PATH)
|
|
|
|
for {
|
|
conn, err := listener.Accept()
|
|
if err != nil {
|
|
log.Printf("Accept error: %v", err)
|
|
continue
|
|
}
|
|
go handleConnection(conn)
|
|
}
|
|
}
|
|
|
|
func execCommand(name string, args ...string) error {
|
|
cmd := exec.Command(name, args...)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
return cmd.Run()
|
|
}
|
|
|
|
func checkGroupExists(group string) bool {
|
|
err := exec.Command("getent", "group", group).Run()
|
|
return err == nil
|
|
}
|
|
|
|
func handleConnection(conn net.Conn) {
|
|
defer conn.Close()
|
|
|
|
decoder := json.NewDecoder(conn)
|
|
encoder := json.NewEncoder(conn)
|
|
|
|
var cmd Command
|
|
if err := decoder.Decode(&cmd); err != nil {
|
|
encoder.Encode(Response{Success: false, Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
var result Response
|
|
switch cmd.Action {
|
|
case "get_users":
|
|
output, err := exec.Command("bash", "-c", "getent passwd | awk -F: '$3 >= 1000 && $7 !~ /(false)/ {print $0}'").CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true, Data: string(output)}
|
|
}
|
|
|
|
case "create_user":
|
|
username := cmd.Params["username"].(string)
|
|
password := cmd.Params["password"].(string)
|
|
group := cmd.Params["group"].(string)
|
|
shell := cmd.Params["shell"].(string)
|
|
isAdmin := cmd.Params["is_admin"].(bool)
|
|
|
|
err := createUser(username, password, group, shell, isAdmin)
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true}
|
|
}
|
|
|
|
case "modify_user_passwd":
|
|
username := cmd.Params["username"].(string)
|
|
password := cmd.Params["password"].(string)
|
|
result = modifyUserPassword(username, password)
|
|
|
|
case "delete_user":
|
|
username := cmd.Params["username"].(string)
|
|
output, err := exec.Command("sudo", "deluser", username).CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Data: fmt.Sprintf("error delete user: %s", err)}
|
|
} else {
|
|
result = Response{Success: true, Data: string(output)}
|
|
}
|
|
|
|
case "get_samba_status":
|
|
output, err := exec.Command("smbstatus", "-f").CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true, Data: string(output)}
|
|
}
|
|
|
|
case "get_groups":
|
|
output, err := exec.Command("bash", "-c", "getent group | awk -F: '$3 >= 1000 {print $1}'").CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true, Data: strings.TrimSpace(string(output))}
|
|
}
|
|
|
|
case "get_user_groups":
|
|
username := cmd.Params["username"].(string)
|
|
|
|
// Get all groups for the user
|
|
groupOutput, err := exec.Command("groups", username).CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
break
|
|
}
|
|
|
|
// Get group details with GIDs
|
|
allGroupsOutput, err := exec.Command("bash", "-c", "getent group | awk -F: '$3 >= 1000 {print $1}'").CombinedOutput()
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
break
|
|
}
|
|
|
|
// Extract user groups and filter against user-created groups
|
|
userGroups := strings.Fields(string(groupOutput))[2:]
|
|
userCreatedGroups := strings.Split(strings.TrimSpace(string(allGroupsOutput)), "\n")
|
|
|
|
// Filter user groups to include only those in user-created groups
|
|
var filteredGroups []string
|
|
for _, group := range userGroups {
|
|
for _, userGroup := range userCreatedGroups {
|
|
if group == userGroup {
|
|
filteredGroups = append(filteredGroups, group)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
result = Response{Success: true, Data: filteredGroups}
|
|
|
|
case "add_user_to_group":
|
|
username := cmd.Params["username"].(string)
|
|
group := cmd.Params["group"].(string)
|
|
err := addUserToGroup(username, group)
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true}
|
|
}
|
|
|
|
case "remove_user_from_group":
|
|
username := cmd.Params["username"].(string)
|
|
group := cmd.Params["group"].(string)
|
|
err := removeUserFromGroup(username, group)
|
|
if err != nil {
|
|
result = Response{Success: false, Error: err.Error()}
|
|
} else {
|
|
result = Response{Success: true}
|
|
}
|
|
|
|
case "get_samba_settings":
|
|
result = getSambaSettings()
|
|
|
|
case "update_section_setting":
|
|
jsonConfig, ok := cmd.Params["config"].(string)
|
|
if !ok {
|
|
result = Response{Success: false, Error: "Invalid or missing config parameter"}
|
|
break
|
|
}
|
|
result = updateSectionSetting(jsonConfig)
|
|
|
|
case "get_samba_service_info":
|
|
result = getSambaServiceInfo()
|
|
|
|
case "restart_samba_service":
|
|
result = restartSambaService()
|
|
|
|
}
|
|
encoder.Encode(result)
|
|
}
|
|
|
|
func modifyUserPassword(username string, password string) Response {
|
|
cmd := exec.Command("sudo", "chpasswd")
|
|
cmd.Stdin = strings.NewReader(fmt.Sprintf("%s:%s", username, password))
|
|
|
|
cmd = exec.Command("sudo", "smbpasswd", "-a", username)
|
|
|
|
// Create a pipe to handle multiple password inputs
|
|
r, w := io.Pipe()
|
|
cmd.Stdin = r
|
|
|
|
// Write passwords to pipe
|
|
go func() {
|
|
defer w.Close()
|
|
w.Write([]byte(fmt.Sprintf("%s\n%s\n", password, password)))
|
|
}()
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return Response{Success: false, Data: fmt.Sprintf("error changing password: %s", err)}
|
|
}
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
return Response{Success: false, Data: fmt.Sprintf("error changing password: %s", err)}
|
|
}
|
|
return Response{Success: true, Data: "Change password success"}
|
|
}
|
|
|
|
func createUser(username, password, group string, shell string, isAdmin bool) error {
|
|
if group == "" {
|
|
group = "sambashare"
|
|
}
|
|
|
|
if err := execCommand("sudo", "useradd", "-M", "-s", shell, "-g", group, username); err != nil {
|
|
return fmt.Errorf("error creating user: %w", err)
|
|
}
|
|
|
|
cmd := exec.Command("sudo", "chpasswd")
|
|
cmd.Stdin = strings.NewReader(fmt.Sprintf("%s:%s", username, password))
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("error setting user password: %w", err)
|
|
}
|
|
|
|
if checkGroupExists(group) {
|
|
if err := execCommand("sudo", "usermod", "-aG", group, username); err != nil {
|
|
return fmt.Errorf("error adding user to group: %w", err)
|
|
}
|
|
} else {
|
|
fmt.Printf("Warning: Group '%s' does not exist.\n", group)
|
|
}
|
|
|
|
if err := execCommand("sudo", "usermod", "-L", username); err != nil {
|
|
return fmt.Errorf("error locking user account: %w", err)
|
|
}
|
|
|
|
if err := execCommand("sudo", "usermod", "-s", shell, username); err != nil {
|
|
return fmt.Errorf("error setting shell: %w", err)
|
|
}
|
|
|
|
// Add user to Samba
|
|
smbCmd := exec.Command("sudo", "smbpasswd", "-a", username)
|
|
smbCmd.Stdin = strings.NewReader(fmt.Sprintf("%s\n%s\n", password, password))
|
|
if err := smbCmd.Run(); err != nil {
|
|
return fmt.Errorf("error adding user to Samba: %w", err)
|
|
}
|
|
|
|
fmt.Printf("User '%s' created successfully and configured for Samba access.\n", username)
|
|
return nil
|
|
}
|
|
|
|
func addUserToGroup(username, group string) error {
|
|
// Use gpasswd to add the user to the group
|
|
cmd := exec.Command("sudo", "gpasswd", "-a", username, group)
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("error adding user to group: %w", err)
|
|
}
|
|
fmt.Printf("User '%s' added to group '%s'.\n", username, group)
|
|
return nil
|
|
}
|
|
|
|
func removeUserFromGroup(username, group string) error {
|
|
// Use gpasswd to remove the user from the group
|
|
cmd := exec.Command("sudo", "gpasswd", "-d", username, group)
|
|
if err := cmd.Run(); err != nil {
|
|
return fmt.Errorf("error removing user from group: %w", err)
|
|
}
|
|
fmt.Printf("User '%s' removed from group '%s'.\n", username, group)
|
|
return nil
|
|
}
|
|
|
|
func getSambaSettings() Response {
|
|
config, err := utils.NewSambaConfig("/etc/samba/smb.conf")
|
|
if err != nil {
|
|
return Response{Success: false, Error: fmt.Sprintf("Error creating config: %v", err)}
|
|
}
|
|
|
|
if err := config.LoadConfig(); err != nil {
|
|
return Response{Success: false, Error: fmt.Sprintf("Error loading config: %v", err)}
|
|
}
|
|
|
|
jsonData, err := json.Marshal(config)
|
|
if err != nil {
|
|
return Response{Success: false, Error: fmt.Sprintf("Error converting to JSON: %v", err)}
|
|
}
|
|
|
|
return Response{Success: true, Data: string(jsonData)}
|
|
}
|
|
|
|
func updateSectionSetting(jsonConfig string) Response {
|
|
config, err := utils.NewSambaConfig("/etc/samba/smb.conf")
|
|
if err != nil {
|
|
return Response{Success: false, Error: fmt.Sprintf("Error creating config: %v", err)}
|
|
}
|
|
|
|
if err := config.SaveConfig(jsonConfig); err != nil {
|
|
return Response{Success: false, Error: fmt.Sprintf("Error saving config: %v", err)}
|
|
}
|
|
|
|
return Response{Success: true, Data: "Configuration updated successfully"}
|
|
}
|
|
|
|
func getSambaServiceInfo() Response {
|
|
// service smbd restart
|
|
output, err := exec.Command("sudo", "smbstatus", "-j").CombinedOutput()
|
|
if err != nil {
|
|
return Response{Success: false, Data: fmt.Errorf("error to get samba status infomation: %w", err)}
|
|
}
|
|
fmt.Println("Success getting smb status")
|
|
return Response{Success: true, Data: string(output)}
|
|
}
|
|
|
|
func restartSambaService() Response {
|
|
// service smbd restart
|
|
cmd := exec.Command("sudo", "service", "smbd", "restart")
|
|
if err := cmd.Run(); err != nil {
|
|
return Response{Success: false, Data: fmt.Errorf("error to restart smbd service: %w", err)}
|
|
}
|
|
fmt.Println("Success restart samba service")
|
|
return Response{Success: true, Data: "Success restart samba service"}
|
|
}
|