123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- package samba
- import (
- "encoding/json"
- "log"
- "net/http"
- "path/filepath"
- "strings"
- "imuslab.com/arozos/mod/utils"
- )
- // Get current samba service status
- func (s *ShareManager) SmbdStates(w http.ResponseWriter, r *http.Request) {
- set, err := utils.PostPara(r, "set")
- if err != nil {
- //return the current smbd states
- smbdRunning, err := IsSmbdRunning()
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- js, _ := json.Marshal(smbdRunning)
- utils.SendJSONResponse(w, string(js))
- return
- } else if set == "enable" {
- //Set smbd to enable
- err = SetSmbdEnableState(true)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- return
- } else if set == "disable" {
- //Set smbd to disable
- err = SetSmbdEnableState(false)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- return
- }
- utils.SendErrorResponse(w, "not support set state: "+set+". Only support enable /disable")
- }
- // List all the samba shares
- func (s *ShareManager) ListSambaShares(w http.ResponseWriter, r *http.Request) {
- shares, err := s.ReadSambaShares()
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- //Remove those shares that is reserved by systems
- shares = s.FilterSystemCreatedShares(shares)
- js, _ := json.Marshal(shares)
- utils.SendJSONResponse(w, string(js))
- }
- // Add a samba share
- func (s *ShareManager) AddSambaShare(w http.ResponseWriter, r *http.Request) {
- shareName, err := utils.PostPara(r, "name")
- if err != nil {
- utils.SendErrorResponse(w, "share name not given")
- return
- }
- shareName = strings.TrimSpace(shareName)
- //Check if this share name already been used
- shareNameExists, err := s.ShareNameExists(shareName)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- if shareNameExists {
- utils.SendErrorResponse(w, "share with identical name already exists")
- return
- }
- sharePath, err := utils.PostPara(r, "path")
- if err != nil {
- utils.SendErrorResponse(w, "share path not given")
- return
- }
- //Parse the path to absolute path
- absoluteSharePath, err := filepath.Abs(sharePath)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- //Check if path exists
- if !utils.FileExists(absoluteSharePath) {
- utils.SendErrorResponse(w, "target path not exists")
- return
- }
- //Check if target path is a folder
- if !utils.IsDir(absoluteSharePath) {
- utils.SendErrorResponse(w, "target path is not a directory")
- return
- }
- //Check if it is a reserved / protected path
- if isPathInsideImportantFolders(absoluteSharePath) {
- utils.SendErrorResponse(w, "system reserved path cannot be shared")
- return
- }
- validUsersJSON, err := utils.PostPara(r, "users")
- if err != nil {
- utils.SendErrorResponse(w, "no valid user givens")
- return
- }
- //Parse valid users into string slice
- validUsers := []string{}
- err = json.Unmarshal([]byte(validUsersJSON), &validUsers)
- if err != nil {
- utils.SendErrorResponse(w, "unable to parse JSON for valid users")
- return
- }
- //Check if all the users exists in the host OS
- for _, validUser := range validUsers {
- thisUnixUserExists, err := s.SambaUserExists(validUser)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- if !thisUnixUserExists {
- //This user not exists
- utils.SendErrorResponse(w, validUser+" is not a valid unix user")
- return
- }
- }
- readOnly, err := utils.PostBool(r, "readonly")
- if err != nil {
- readOnly = false
- }
- browseable, err := utils.PostBool(r, "browseable")
- if err != nil {
- browseable = true
- }
- allowGuest, err := utils.PostBool(r, "guestok")
- if err != nil {
- allowGuest = false
- }
- shareToCreate := ShareConfig{
- Name: shareName,
- Path: absoluteSharePath,
- ValidUsers: validUsers,
- ReadOnly: readOnly,
- Browseable: browseable,
- GuestOk: allowGuest,
- }
- //Add the new share to smb.conf
- err = s.CreateNewSambaShare(&shareToCreate)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- //Restart smbd
- err = restartSmbd()
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- }
- // Remove a samba share by name
- func (s *ShareManager) DelSambaShare(w http.ResponseWriter, r *http.Request) {
- shareName, err := utils.PostPara(r, "name")
- if err != nil {
- utils.SendErrorResponse(w, "share name not given")
- return
- }
- //Check if share exists
- shareExists, err := s.ShareExists(shareName)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- if !shareExists {
- utils.SendErrorResponse(w, "share to be remove not exists")
- return
- }
- //Remove the share from config file
- err = s.RemoveSambaShareConfig(shareName)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- //Restart smbd
- err = restartSmbd()
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- }
- // Add a new samba user
- func (s *ShareManager) NewSambaUser(w http.ResponseWriter, r *http.Request) {
- username, err := utils.PostPara(r, "username")
- if err != nil {
- utils.SendErrorResponse(w, "username not given")
- return
- }
- password, err := utils.PostPara(r, "password")
- if err != nil {
- utils.SendErrorResponse(w, "password not set")
- return
- }
- err = s.AddSambaUser(username, password)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- }
- // Remove a samba user, check for admin before calling
- func (s *ShareManager) DelSambaUser(w http.ResponseWriter, r *http.Request) {
- username, err := utils.PostPara(r, "username")
- if err != nil {
- utils.SendErrorResponse(w, "username not given")
- return
- }
- //Remove the samba user
- err = s.RemoveSmbUser(username)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- utils.SendOK(w)
- }
- // List all samba users info
- func (s *ShareManager) ListSambaUsers(w http.ResponseWriter, r *http.Request) {
- userInfo, err := s.ListSambaUsersInfo()
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- js, _ := json.Marshal(userInfo)
- utils.SendJSONResponse(w, string(js))
- }
- // Activate a user account from arozos into samba user
- func (s *ShareManager) ActivateUserAccount(w http.ResponseWriter, r *http.Request, username string, password string) {
- //Register this user to samba if not exists
- sambaUserExists, err := s.SambaUserExists(username)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- userInfo, _ := s.UserHandler.GetUserInfoFromRequest(w, r)
- if !sambaUserExists {
- //This user account not activated yet. Activate it
- err = s.AddSambaUser(userInfo.Username, password)
- if err != nil {
- utils.SendErrorResponse(w, err.Error())
- return
- }
- }
- //Create the user root share folders
- for _, fsh := range userInfo.GetAllAccessibleFileSystemHandler() {
- if fsh.IsLocalDrive() {
- //Samba can only work with drives locally hosted on this server
- fshID := fsh.UUID
- fshSharePath := fsh.Path
- if fsh.RequierUserIsolation() {
- //User seperated storage. Only mount the user one
- fshID = fsh.UUID + "_" + userInfo.Username
- fshSharePath = filepath.Join(fsh.Path, "/users/", userInfo.Username+"/")
- }
- fshID = sanitizeShareName(fshID)
- //Check if the share already exists
- shareExists, err := s.ShareExists(fshID)
- if err != nil {
- continue
- }
- if !shareExists {
- //Try to create the share
- fshShareAbsolutePath, err := filepath.Abs(fshSharePath)
- if err != nil {
- log.Println("[Samba] Unable to generate share config for path: " + fshSharePath)
- continue
- }
- //Check if that folder exists
- if utils.FileExists(fshShareAbsolutePath) {
- //Folder not exists. Continue
- log.Println("[Samba] Path not exists for file system handler: " + fshSharePath)
- continue
- }
- //Ok! Create the share with this username
- err = s.CreateNewSambaShare(&ShareConfig{
- Name: fshID,
- Path: fshShareAbsolutePath,
- ValidUsers: []string{userInfo.Username},
- ReadOnly: false,
- Browseable: true,
- GuestOk: false,
- })
- if err != nil {
- log.Println("[Samba] Failed to create share: " + err.Error())
- utils.SendErrorResponse(w, err.Error())
- return
- }
- } else {
- //Share exists. Add this user to such share
- err = s.AddUserToSambaShare(fshID, userInfo.Username)
- if err != nil {
- log.Println("[Samba] Failed to add user " + userInfo.Username + " to share " + fshID + ": " + err.Error())
- utils.SendErrorResponse(w, err.Error())
- return
- }
- }
- }
- }
- utils.SendOK(w)
- }
|