mirror of
https://github.com/restic/restic.git
synced 2025-03-16 00:00:05 +01:00
99 lines
3.6 KiB
Go
99 lines
3.6 KiB
Go
package smb
|
|
|
|
import (
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/restic/restic/internal/errors"
|
|
"github.com/restic/restic/internal/options"
|
|
)
|
|
|
|
// Config contains all configuration necessary to connect to an SMB server
|
|
type Config struct {
|
|
Address string
|
|
Port int
|
|
ShareName string
|
|
Path string
|
|
|
|
User string `option:"user" help:"specify the SMB user for NTLM authentication."`
|
|
Password options.SecretString `option:"password" help:"specify the SMB password for NTLM authentication."`
|
|
Domain string `option:"domain" help:"specify the domain for authentication."`
|
|
|
|
Layout string `option:"layout" help:"use this backend directory layout (default: auto-detect)"`
|
|
Connections uint `option:"connections" help:"set a limit for the number of concurrent operations (default: 2)"`
|
|
IdleTimeout time.Duration `option:"idle-timeout" help:"Max time in seconds before closing idle connections. If no connections have been returned to the connection pool in the time given, the connection pool will be emptied. Set to 0 to keep connections indefinitely.(default: 60)"`
|
|
RequireMessageSigning bool `option:"require-message-signing" help:"Mandates message signing otherwise does not allow the connection. If this is false, messaging signing is just enabled and not enforced. (default: false)"`
|
|
Dialect uint16 `option:"dialect" help:"Force a specific dialect to be used. SMB311:785, SMB302:770, SMB300:768, SMB210:528, SMB202:514, SMB2:767. If unspecfied (0), following dialects are tried in order - SMB311, SMB302, SMB300, SMB210, SMB202 (default: 0)"`
|
|
ClientGuid string `option:"client-guid" help:"A 16-byte GUID to uniquely identify a client. If not specific a random GUID is used. (default: \"\")"`
|
|
}
|
|
|
|
const (
|
|
DefaultSmbPort int = 445
|
|
DefaultDomain string = "WORKGROUP"
|
|
DefaultConnections uint = 2
|
|
DefaultIdleTimeout time.Duration = 60 * time.Second
|
|
)
|
|
|
|
// NewConfig returns a new Config with the default values filled in.
|
|
func NewConfig() Config {
|
|
return Config{
|
|
Port: DefaultSmbPort,
|
|
Domain: DefaultDomain,
|
|
IdleTimeout: DefaultIdleTimeout,
|
|
Connections: DefaultConnections,
|
|
}
|
|
}
|
|
|
|
func init() {
|
|
options.Register("smb", Config{})
|
|
}
|
|
|
|
// ParseConfig parses the string s and extracts the s3 config. The two
|
|
// supported configuration formats are smb://address:port/sharename/directory and
|
|
// smb://address/sharename/directory in which case default port 445 is used.
|
|
// If no prefix is given the prefix "restic" will be used.
|
|
func ParseConfig(s string) (interface{}, error) {
|
|
switch {
|
|
case strings.HasPrefix(s, "smb://"):
|
|
s = s[6:]
|
|
case strings.HasPrefix(s, "smb:"):
|
|
s = s[4:]
|
|
default:
|
|
return nil, errors.New("smb: invalid format")
|
|
}
|
|
// use the first entry of the path as the endpoint and the
|
|
// remainder as bucket name and prefix
|
|
fullAddress, rest, _ := strings.Cut(s, "/")
|
|
address, portString, hasPort := strings.Cut(fullAddress, ":")
|
|
var port int
|
|
if !hasPort {
|
|
port = DefaultSmbPort
|
|
} else {
|
|
var err error
|
|
port, err = strconv.Atoi(portString)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
sharename, directory, _ := strings.Cut(rest, "/")
|
|
return createConfig(address, port, sharename, directory)
|
|
}
|
|
|
|
func createConfig(address string, port int, sharename string, directory string) (interface{}, error) {
|
|
if address == "" {
|
|
return nil, errors.New("smb: invalid format, address not found")
|
|
}
|
|
|
|
if directory != "" {
|
|
directory = path.Clean(directory)
|
|
}
|
|
|
|
cfg := NewConfig()
|
|
cfg.Address = address
|
|
cfg.Port = port
|
|
cfg.ShareName = sharename
|
|
cfg.Path = directory
|
|
return cfg, nil
|
|
}
|