webdav: add support for sharepoint with NTLM authentication (#2921)

Add new option option "sharepoint-ntlm" for the vendor setting.
Use it when your hosted Sharepoint is not tied to the OneDrive
accounts and uses NTLM authentication.
Also add documentation and integration test.

Fixes: #2171
This commit is contained in:
Rauno Ots 2019-01-17 13:35:30 +01:00 committed by Ivan Andreev
parent cc08f66dc1
commit 9808a53416
5 changed files with 70 additions and 7 deletions

View File

@ -33,6 +33,8 @@ import (
"github.com/rclone/rclone/fs/hash" "github.com/rclone/rclone/fs/hash"
"github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/pacer"
"github.com/rclone/rclone/lib/rest" "github.com/rclone/rclone/lib/rest"
ntlmssp "github.com/Azure/go-ntlmssp"
) )
const ( const (
@ -67,14 +69,17 @@ func init() {
Help: "Owncloud", Help: "Owncloud",
}, { }, {
Value: "sharepoint", Value: "sharepoint",
Help: "Sharepoint", Help: "Sharepoint Online, authenticated by Microsoft OneDrive account.",
}, {
Value: "sharepoint-ntlm",
Help: "Sharepoint with NTLM authentication. Usually self-hosted or company instances.",
}, { }, {
Value: "other", Value: "other",
Help: "Other site/service or software", Help: "Other site/service or software",
}}, }},
}, { }, {
Name: "user", Name: "user",
Help: "User name", Help: "User name. In case NTLM authentication is used, the username should be in the format 'Domain\\User'.",
}, { }, {
Name: "pass", Name: "pass",
Help: "Password.", Help: "Password.",
@ -330,13 +335,18 @@ func NewFs(ctx context.Context, name, root string, m configmap.Mapper) (fs.Fs, e
return nil, err return nil, err
} }
client := fshttp.NewClient(ctx)
if opt.Vendor == "sharepoint-ntlm" {
// Add NTLM layer
client.Transport = ntlmssp.Negotiator{RoundTripper: client.Transport}
}
f := &Fs{ f := &Fs{
name: name, name: name,
root: root, root: root,
opt: *opt, opt: *opt,
endpoint: u, endpoint: u,
endpointURL: u.String(), endpointURL: u.String(),
srv: rest.NewClient(fshttp.NewClient(ctx)).SetRoot(u.String()), srv: rest.NewClient(client).SetRoot(u.String()),
pacer: fs.NewPacer(ctx, pacer.NewDefault(pacer.MinSleep(minSleep), pacer.MaxSleep(maxSleep), pacer.DecayConstant(decayConstant))), pacer: fs.NewPacer(ctx, pacer.NewDefault(pacer.MinSleep(minSleep), pacer.MaxSleep(maxSleep), pacer.DecayConstant(decayConstant))),
precision: fs.ModTimeNotSupported, precision: fs.ModTimeNotSupported,
} }
@ -465,6 +475,10 @@ func (f *Fs) setQuirks(ctx context.Context, vendor string) error {
// to determine if we may have found a file, the request has to be resent // to determine if we may have found a file, the request has to be resent
// with the depth set to 0 // with the depth set to 0
f.retryWithZeroDepth = true f.retryWithZeroDepth = true
case "sharepoint-ntlm":
// Sharepoint with NTLM authentication
// See comment above
f.retryWithZeroDepth = true
case "other": case "other":
default: default:
fs.Debugf(f, "Unknown vendor %q", vendor) fs.Debugf(f, "Unknown vendor %q", vendor)

View File

@ -38,3 +38,14 @@ func TestIntegration3(t *testing.T) {
NilObject: (*webdav.Object)(nil), NilObject: (*webdav.Object)(nil),
}) })
} }
// TestIntegration runs integration tests against the remote
func TestIntegration4(t *testing.T) {
if *fstest.RemoteName != "" {
t.Skip("skipping as -remote is set")
}
fstests.Run(t, &fstests.Opt{
RemoteName: "TestWebdavNTLM:",
NilObject: (*webdav.Object)(nil),
})
}

View File

@ -45,9 +45,11 @@ Choose a number from below, or type in your own value
\ "nextcloud" \ "nextcloud"
2 / Owncloud 2 / Owncloud
\ "owncloud" \ "owncloud"
3 / Sharepoint 3 / Sharepoint Online, authenticated by Microsoft OneDrive account.
\ "sharepoint" \ "sharepoint"
4 / Other site/service or software 4 / Sharepoint with NTLM authentication. Usually self-hosted instances.
\ "sharepoint-ntlm"
5 / Other site/service or software
\ "other" \ "other"
vendor> 1 vendor> 1
User name User name
@ -136,6 +138,8 @@ Name of the Webdav site/service/software you are using
- Owncloud - Owncloud
- "sharepoint" - "sharepoint"
- Sharepoint - Sharepoint
- "sharepoint-ntlm"
- Sharepoint with NTLM authentication
- "other" - "other"
- Other site/service or software - Other site/service or software
@ -148,6 +152,8 @@ User name
- Type: string - Type: string
- Default: "" - Default: ""
In case vendor mode `sharepoint-ntlm` is used, the user name is in the form `DOMAIN\user`
#### --webdav-pass #### --webdav-pass
Password. Password.
@ -201,7 +207,7 @@ This is configured in an identical way to Owncloud. Note that
Nextcloud initially did not support streaming of files (`rcat`) whereas Nextcloud initially did not support streaming of files (`rcat`) whereas
Owncloud did, but [this](https://github.com/nextcloud/nextcloud-snap/issues/365) seems to be fixed as of 2020-11-27 (tested with rclone v1.53.1 and Nextcloud Server v19). Owncloud did, but [this](https://github.com/nextcloud/nextcloud-snap/issues/365) seems to be fixed as of 2020-11-27 (tested with rclone v1.53.1 and Nextcloud Server v19).
### Sharepoint ### ### Sharepoint OneDrive ###
Rclone can be used with Sharepoint provided by OneDrive for Business Rclone can be used with Sharepoint provided by OneDrive for Business
or Office365 Education Accounts. or Office365 Education Accounts.
@ -237,11 +243,40 @@ Your config file should look like this:
[sharepoint] [sharepoint]
type = webdav type = webdav
url = https://[YOUR-DOMAIN]-my.sharepoint.com/personal/[YOUR-EMAIL]/Documents url = https://[YOUR-DOMAIN]-my.sharepoint.com/personal/[YOUR-EMAIL]/Documents
vendor = other vendor = sharepoint
user = YourEmailAddress user = YourEmailAddress
pass = encryptedpassword pass = encryptedpassword
``` ```
### Sharepoint with NTLM ###
Use this option in case your (hosted) Sharepoint is not tied to OneDrive accounts and uses NTLM authentication.
For getting the `url` configuration, similarly to the above, first navigate to the desired directory in your browser to get the URL,
then strip everything after the name of the opened directory.
Example:
If the URL is:
https://example.sharepoint.com/sites/12345/Documents/Forms/AllItems.aspx
The configuration to use would be:
https://example.sharepoint.com/sites/12345/Documents
Set the `vendor` to `sharepoint-ntlm`.
NTLM uses domain and user name combination for authentication,
set `user` to `DOMAIN\username`.
Your config file should look like this:
```
[sharepoint]
type = webdav
url = https://[YOUR-DOMAIN]/some-path-to/Documents
vendor = sharepoint-ntlm
user = DOMAIN\user
pass = encryptedpassword
```
#### Required Flags for SharePoint #### #### Required Flags for SharePoint ####
As SharePoint does some special things with uploaded documents, you won't be able to use the documents size or the documents hash to compare if a file has been changed since the upload / which file is newer. As SharePoint does some special things with uploaded documents, you won't be able to use the documents size or the documents hash to compare if a file has been changed since the upload / which file is newer.

1
go.mod
View File

@ -8,6 +8,7 @@ require (
github.com/Azure/azure-pipeline-go v0.2.3 github.com/Azure/azure-pipeline-go v0.2.3
github.com/Azure/azure-storage-blob-go v0.13.0 github.com/Azure/azure-storage-blob-go v0.13.0
github.com/Azure/go-autorest/autorest/adal v0.9.10 github.com/Azure/go-autorest/autorest/adal v0.9.10
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c
github.com/Microsoft/go-winio v0.4.16 // indirect github.com/Microsoft/go-winio v0.4.16 // indirect
github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8 github.com/Unknwon/goconfig v0.0.0-20200908083735-df7de6a44db8
github.com/a8m/tree v0.0.0-20210115125333-10a5fd5b637d github.com/a8m/tree v0.0.0-20210115125333-10a5fd5b637d

2
go.sum
View File

@ -55,6 +55,8 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPu
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=