|
@@ -3,8 +3,11 @@ package samba
|
|
|
import (
|
|
|
"bufio"
|
|
|
"fmt"
|
|
|
+ "io"
|
|
|
"os"
|
|
|
+ "path/filepath"
|
|
|
"strings"
|
|
|
+ "time"
|
|
|
)
|
|
|
|
|
|
/*
|
|
@@ -17,7 +20,8 @@ import (
|
|
|
*/
|
|
|
|
|
|
type ShareManager struct {
|
|
|
- SambaConfigPath string
|
|
|
+ SambaConfigPath string //Config file for samba, aka smb.conf
|
|
|
+ BackupDir string //Backup directory for restoring previous config
|
|
|
}
|
|
|
|
|
|
type ShareConfig struct {
|
|
@@ -32,6 +36,7 @@ type ShareConfig struct {
|
|
|
func NewSambaShareManager() *ShareManager {
|
|
|
return &ShareManager{
|
|
|
SambaConfigPath: "/etc/samba/smb.conf",
|
|
|
+ BackupDir: "./backup",
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -98,16 +103,50 @@ func (s *ShareManager) ReadSambaShares() ([]ShareConfig, error) {
|
|
|
return shares, nil
|
|
|
}
|
|
|
|
|
|
-// AppendSambaShareConfig appends the Samba share configuration to smb.conf
|
|
|
-func (s *ShareManager) AppendSambaShareConfig(config string) error {
|
|
|
- file, err := os.OpenFile(s.SambaConfigPath, os.O_APPEND|os.O_WRONLY, 0644)
|
|
|
+// CreateNewSambaShare converts the shareConfig to string and appends it to smb.conf if the share name does not already exist
|
|
|
+func (s *ShareManager) CreateNewSambaShare(shareToCreate *ShareConfig) error {
|
|
|
+ // Path to smb.conf
|
|
|
+ smbConfPath := s.SambaConfigPath
|
|
|
+
|
|
|
+ // Open the smb.conf file for reading
|
|
|
+ file, err := os.Open(smbConfPath)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return fmt.Errorf("failed to open smb.conf: %v", err)
|
|
|
}
|
|
|
defer file.Close()
|
|
|
|
|
|
- if _, err := file.WriteString(config); err != nil {
|
|
|
- return err
|
|
|
+ // Check if the share already exists
|
|
|
+ scanner := bufio.NewScanner(file)
|
|
|
+ shareExists := false
|
|
|
+ shareNameSection := fmt.Sprintf("[%s]", shareToCreate.Name)
|
|
|
+ for scanner.Scan() {
|
|
|
+ if strings.TrimSpace(scanner.Text()) == shareNameSection {
|
|
|
+ shareExists = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := scanner.Err(); err != nil {
|
|
|
+ return fmt.Errorf("failed to read smb.conf: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if shareExists {
|
|
|
+ return fmt.Errorf("share %s already exists", shareToCreate.Name)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Convert ShareConfig to string
|
|
|
+ shareConfigString := convertShareConfigToString(shareToCreate)
|
|
|
+
|
|
|
+ // Open the smb.conf file for appending
|
|
|
+ file, err = os.OpenFile(smbConfPath, os.O_APPEND|os.O_WRONLY, 0644)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to open smb.conf for writing: %v", err)
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ // Append the new share configuration
|
|
|
+ if _, err := file.WriteString(shareConfigString); err != nil {
|
|
|
+ return fmt.Errorf("failed to write to smb.conf: %v", err)
|
|
|
}
|
|
|
|
|
|
return nil
|
|
@@ -174,3 +213,70 @@ func (s *ShareManager) RemoveSambaShareConfig(shareName string) error {
|
|
|
|
|
|
return nil
|
|
|
}
|
|
|
+
|
|
|
+// ShareExists checks if a given share name exists in smb.conf
|
|
|
+func (s *ShareManager) ShareExists(shareName string) (bool, error) {
|
|
|
+ // Path to smb.conf
|
|
|
+ smbConfPath := s.SambaConfigPath
|
|
|
+
|
|
|
+ // Open the smb.conf file for reading
|
|
|
+ file, err := os.Open(smbConfPath)
|
|
|
+ if err != nil {
|
|
|
+ return false, fmt.Errorf("failed to open smb.conf: %v", err)
|
|
|
+ }
|
|
|
+ defer file.Close()
|
|
|
+
|
|
|
+ // Check if the share already exists
|
|
|
+ scanner := bufio.NewScanner(file)
|
|
|
+ shareNameSection := fmt.Sprintf("[%s]", shareName)
|
|
|
+ for scanner.Scan() {
|
|
|
+ if strings.TrimSpace(scanner.Text()) == shareNameSection {
|
|
|
+ return true, nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := scanner.Err(); err != nil {
|
|
|
+ return false, fmt.Errorf("failed to read smb.conf: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return false, nil
|
|
|
+}
|
|
|
+
|
|
|
+// Backup the current smb.conf to the backup folder
|
|
|
+func (s *ShareManager) BackupSmbConf() error {
|
|
|
+ // Define source and backup directory
|
|
|
+ sourceFile := s.SambaConfigPath
|
|
|
+ backupDir := s.BackupDir
|
|
|
+
|
|
|
+ // Ensure the backup directory exists
|
|
|
+ err := os.MkdirAll(backupDir, 0755)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to create backup directory: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create a timestamped backup filename
|
|
|
+ timestamp := time.Now().Format("20060102_150405")
|
|
|
+ backupFile := filepath.Join(backupDir, fmt.Sprintf("%s.smb.conf", timestamp))
|
|
|
+
|
|
|
+ // Open the source file
|
|
|
+ src, err := os.Open(sourceFile)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to open source file: %v", err)
|
|
|
+ }
|
|
|
+ defer src.Close()
|
|
|
+
|
|
|
+ // Create the destination file
|
|
|
+ dst, err := os.Create(backupFile)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to create backup file: %v", err)
|
|
|
+ }
|
|
|
+ defer dst.Close()
|
|
|
+
|
|
|
+ // Copy the contents of the source file to the backup file
|
|
|
+ _, err = io.Copy(dst, src)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to copy file contents: %v", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|