smbuser.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package samba
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os/exec"
  6. "regexp"
  7. "strings"
  8. )
  9. // samba user info
  10. type UserInfo struct {
  11. UnixUsername string
  12. UserSID string
  13. Domain string
  14. LastBadPassword string
  15. BadPasswordCount int
  16. }
  17. // AddSambaUser adds a Samba user with the given username
  18. func (s *ShareManager) AddSambaUser(username string, password string) error {
  19. // Check if the user already exists
  20. if !unixUserExists(username) {
  21. //Create unix user
  22. cmd := exec.Command("sudo", "adduser", "--no-create-home", "--disabled-password", "--disabled-login", "--force-badname", username)
  23. err := cmd.Run()
  24. if err != nil {
  25. return fmt.Errorf("failed to add unix user: %v", err)
  26. }
  27. }
  28. //Create samba user
  29. err := s.setupSmbUser(username, password)
  30. if err != nil {
  31. return err
  32. }
  33. return nil
  34. }
  35. // userExists checks if a user exists
  36. func unixUserExists(username string) bool {
  37. // Check if the user exists by attempting to get their home directory
  38. cmd := exec.Command("getent", "passwd", username)
  39. err := cmd.Run()
  40. return err == nil
  41. }
  42. // SetupSmbUser sets up a Samba user account with the given username and password
  43. func (s *ShareManager) setupSmbUser(username, password string) error {
  44. // Execute the smbpasswd command with the specified username
  45. cmd := exec.Command("sudo", "smbpasswd", "-a", username)
  46. // Create a pipe for STDIN to pass the password to the smbpasswd command
  47. stdinPipe, err := cmd.StdinPipe()
  48. if err != nil {
  49. return fmt.Errorf("failed to create STDIN pipe: %v", err)
  50. }
  51. // Start the command
  52. if err := cmd.Start(); err != nil {
  53. return fmt.Errorf("failed to start smbpasswd command: %v", err)
  54. }
  55. // Pass the password twice to the smbpasswd command via STDIN
  56. password = fmt.Sprintf("%s\n%s\n", password, password)
  57. if _, err := stdinPipe.Write([]byte(password)); err != nil {
  58. return fmt.Errorf("failed to write password to smbpasswd command: %v", err)
  59. }
  60. // Close the STDIN pipe to signal the end of input
  61. if err := stdinPipe.Close(); err != nil {
  62. return fmt.Errorf("failed to close STDIN pipe: %v", err)
  63. }
  64. // Wait for the command to finish
  65. if err := cmd.Wait(); err != nil {
  66. return fmt.Errorf("smbpasswd command failed: %v", err)
  67. }
  68. return nil
  69. }
  70. // RemoveSmbUser removes a Samba user account with the given username
  71. func (s *ShareManager) RemoveSmbUser(username string) error {
  72. // Execute the smbpasswd command with the -x flag to delete the user
  73. cmd := exec.Command("sudo", "smbpasswd", "-x", username)
  74. // Run the command
  75. err := cmd.Run()
  76. if err != nil {
  77. return fmt.Errorf("failed to remove Samba user account: %v", err)
  78. }
  79. return nil
  80. }
  81. // RemoveUnixUser removes a Unix user account with the given username
  82. func (s *ShareManager) RemoveUnixUser(username string) error {
  83. // Execute the userdel command with the specified username
  84. cmd := exec.Command("sudo", "userdel", username)
  85. // Run the command
  86. err := cmd.Run()
  87. if err != nil {
  88. return fmt.Errorf("failed to remove Unix user account: %v", err)
  89. }
  90. return nil
  91. }
  92. // ListSambaUsersInfo lists information about Samba users
  93. func (s *ShareManager) ListSambaUsersInfo() ([]UserInfo, error) {
  94. // Execute pdbedit -L -v command
  95. cmd := exec.Command("sudo", "pdbedit", "-L", "-v")
  96. output, err := cmd.CombinedOutput()
  97. if err != nil {
  98. return nil, fmt.Errorf("failed to execute pdbedit command: %v", err)
  99. }
  100. // Parse the output and extract user information
  101. var usersInfo []UserInfo
  102. scanner := bufio.NewScanner(strings.NewReader(string(output)))
  103. var userInfo UserInfo
  104. re := regexp.MustCompile(`^Unix username:\s+(.*)$`)
  105. for scanner.Scan() {
  106. line := scanner.Text()
  107. match := re.FindStringSubmatch(line)
  108. if len(match) > 0 {
  109. if userInfo.UnixUsername != "" {
  110. usersInfo = append(usersInfo, userInfo)
  111. }
  112. userInfo = UserInfo{UnixUsername: match[1]}
  113. } else if strings.HasPrefix(line, "User SID:") {
  114. userInfo.UserSID = strings.TrimSpace(strings.Split(line, ":")[1])
  115. } else if strings.HasPrefix(line, "Domain:") {
  116. userInfo.Domain = strings.TrimSpace(strings.Split(line, ":")[1])
  117. } else if strings.HasPrefix(line, "Last bad password") {
  118. info := strings.TrimSpace(strings.Split(line, ":")[1])
  119. if info != "never" {
  120. userInfo.LastBadPassword = info
  121. }
  122. } else if strings.HasPrefix(line, "Bad password count") {
  123. fmt.Sscanf(strings.TrimSpace(strings.Split(line, ":")[1]), "%d", &userInfo.BadPasswordCount)
  124. }
  125. }
  126. if userInfo.UnixUsername != "" {
  127. usersInfo = append(usersInfo, userInfo)
  128. }
  129. if err := scanner.Err(); err != nil {
  130. return nil, fmt.Errorf("error scanning pdbedit output: %v", err)
  131. }
  132. return usersInfo, nil
  133. }