diff --git a/go.mod b/go.mod
index 090542aa..6a2f0a62 100644
--- a/go.mod
+++ b/go.mod
@@ -9,14 +9,14 @@ require (
github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962
github.com/alexedwards/argon2id v0.0.0-20211130144151-3585854a6387
github.com/aws/aws-sdk-go-v2 v1.17.1
- github.com/aws/aws-sdk-go-v2/config v1.18.1
- github.com/aws/aws-sdk-go-v2/credentials v1.13.1
+ github.com/aws/aws-sdk-go-v2/config v1.18.2
+ github.com/aws/aws-sdk-go-v2/credentials v1.13.2
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19
- github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.40
+ github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.41
github.com/aws/aws-sdk-go-v2/service/marketplacemetering v1.13.23
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.3
- github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.6
- github.com/aws/aws-sdk-go-v2/service/sts v1.17.3
+ github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.7
+ github.com/aws/aws-sdk-go-v2/service/sts v1.17.4
github.com/cockroachdb/cockroach-go/v2 v2.2.18
github.com/coreos/go-oidc/v3 v3.4.0
github.com/drakkan/webdav v0.0.0-20221101181759-17ed21f9337b
@@ -34,7 +34,7 @@ require (
github.com/hashicorp/go-hclog v1.3.1
github.com/hashicorp/go-plugin v1.4.6
github.com/hashicorp/go-retryablehttp v0.7.1
- github.com/jackc/pgx/v5 v5.1.0
+ github.com/jackc/pgx/v5 v5.1.1
github.com/jlaffaye/ftp v0.0.0-20201112195030-9aae4d151126
github.com/klauspost/compress v1.15.12
github.com/lestrrat-go/jwx/v2 v2.0.7
@@ -158,8 +158,8 @@ require (
golang.org/x/tools v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472 // indirect
- google.golang.org/grpc v1.50.1 // indirect
+ google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 // indirect
+ google.golang.org/grpc v1.51.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
diff --git a/go.sum b/go.sum
index fdd8dce6..575c558c 100644
--- a/go.sum
+++ b/go.sum
@@ -233,17 +233,17 @@ github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXK
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9 h1:RKci2D7tMwpvGpDNZnGQw9wk6v7o/xSwFcUAuNPoB8k=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.9/go.mod h1:vCmV1q1VK8eoQJ5+aYE7PkK1K6v41qJ5pJdK3ggCDvg=
github.com/aws/aws-sdk-go-v2/config v1.15.15/go.mod h1:A1Lzyy/o21I5/s2FbyX5AevQfSVXpvvIDCoVFD0BC4E=
-github.com/aws/aws-sdk-go-v2/config v1.18.1 h1:wMzU9tBq/tEdTUcmB9WsYe5stdP0/EAf84vfeqS5S6A=
-github.com/aws/aws-sdk-go-v2/config v1.18.1/go.mod h1:jQIgBmQJa5oPzTUtWMjFryPDCBlVqIgoFmdfFKLx4WE=
+github.com/aws/aws-sdk-go-v2/config v1.18.2 h1:tRhTb3xMZsB0gW0sXWpqs9FeIP8iQp5SvnvwiPXzHwo=
+github.com/aws/aws-sdk-go-v2/config v1.18.2/go.mod h1:9XVoZTdD8ICjrgI5ddb8j918q6lEZkFYpb7uohgvU6c=
github.com/aws/aws-sdk-go-v2/credentials v1.12.10/go.mod h1:g5eIM5XRs/OzIIK81QMBl+dAuDyoLN0VYaLP+tBqEOk=
-github.com/aws/aws-sdk-go-v2/credentials v1.13.1 h1:HusGjp9C8zwu1SSEh3s501Llqr2xhn+FYKV5XMnOt6M=
-github.com/aws/aws-sdk-go-v2/credentials v1.13.1/go.mod h1:C8xoJdzfQq/kl6gGIuJeHpcAaZnraJfTV9FoBgW1QYg=
+github.com/aws/aws-sdk-go-v2/credentials v1.13.2 h1:F/v1w0XcFDZjL0bCdi9XWJenoPKjGbzljBhDKcryzEQ=
+github.com/aws/aws-sdk-go-v2/credentials v1.13.2/go.mod h1:eAT5aj/WJ2UDIA0IVNFc2byQLeD89SDEi4cjzH/MKoQ=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9/go.mod h1:KDCCm4ONIdHtUloDcFvK2+vshZvx4Zmj7UMDfusuz5s=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19 h1:E3PXZSI3F2bzyj6XxUXdTIfvp425HHhwKsFvmzBwHgs=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.19/go.mod h1:VihW95zQpeKQWVPGkwT+2+WJNQV8UXFfMTWdU6VErL8=
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21/go.mod h1:iIYPrQ2rYfZiB/iADYlhj9HHZ9TTi6PqKQPAqygohbE=
-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.40 h1:Q8Pshd76l1y24DSWJrQPyYY6xVNmpcsZHEfE9xZ4rpU=
-github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.40/go.mod h1:rxGAF7fGMCse4bUVO+55P1mWCMCnUZPmh3LAnl0PZms=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.41 h1:ssgdsNm11dvFtO7F/AeiW4dAO3eGsDeg5fwpag/JP/I=
+github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.41/go.mod h1:CS+AbDFAaPU9TQOo7U6mVV23YvqCOElnqmh0XQjgJ1g=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25 h1:nBO/RFxeq/IS5G9Of+ZrgucRciie2qpLy++3UGZ+q2E=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.25/go.mod h1:Zb29PYkf42vVYQY6pvSyJCJcFHlPIiY+YKdPtwnvMkY=
@@ -275,8 +275,8 @@ github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2/go.mod h1:u+566cosFI+d+motIz3USX
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.3 h1:F6wgg8aHGNyhaAy2ONnWBThiPdLa386qNA0j33FIuSM=
github.com/aws/aws-sdk-go-v2/service/s3 v1.29.3/go.mod h1:/NHbqPRiwxSPVOB2Xr+StDEH+GWV/64WwnUjv4KYzV0=
github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.14/go.mod h1:xakbH8KMsQQKqzX87uyyzTHshc/0/Df8bsTneTS5pFU=
-github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.6 h1:TMIXEKw1ak/OPXGBTwBORU4aR921XFbj7pFsDPn45go=
-github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.6/go.mod h1:k6CPuxyzO247nYEM1baEwHH1kRtosRCvgahAepaaShw=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.7 h1:bfC2Q8ABNbYYm9mh3NfPy5kvnWOPtiqS018NBGDwPl8=
+github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.16.7/go.mod h1:k6CPuxyzO247nYEM1baEwHH1kRtosRCvgahAepaaShw=
github.com/aws/aws-sdk-go-v2/service/sns v1.17.10/go.mod h1:uITsRNVMeCB3MkWpXxXw0eDz8pW4TYLzj+eyQtbhSxM=
github.com/aws/aws-sdk-go-v2/service/sqs v1.19.1/go.mod h1:A94o564Gj+Yn+7QO1eLFeI7UVv3riy/YBFOfICVqFvU=
github.com/aws/aws-sdk-go-v2/service/ssm v1.27.6/go.mod h1:fiFzQgj4xNOg4/wqmAiPvzgDMXPD+cUEplX/CYn+0j0=
@@ -286,8 +286,8 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.11.25/go.mod h1:IARHuzTXmj1C0KS35vbo
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8 h1:jcw6kKZrtNfBPJkaHrscDOZoe5gvi9wjudnxvozYFJo=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.8/go.mod h1:er2JHN+kBY6FcMfcBBKNGCT3CarImmdFzishsqBmSRI=
github.com/aws/aws-sdk-go-v2/service/sts v1.16.10/go.mod h1:cftkHYN6tCDNfkSasAmclSfl4l7cySoay8vz7p/ce0E=
-github.com/aws/aws-sdk-go-v2/service/sts v1.17.3 h1:WMAsVk4yQTHOZ2m7dFnF5Azr/aDecBbpWRwc+M6iFIM=
-github.com/aws/aws-sdk-go-v2/service/sts v1.17.3/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4=
+github.com/aws/aws-sdk-go-v2/service/sts v1.17.4 h1:YNncBj5dVYd05i4ZQ+YicOotSXo0ufc9P8kTioi13EM=
+github.com/aws/aws-sdk-go-v2/service/sts v1.17.4/go.mod h1:bXcN3koeVYiJcdDU89n3kCYILob7Y34AeLopUbZgLT4=
github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
github.com/aws/smithy-go v1.13.4 h1:/RN2z1txIJWeXeOkzX+Hk/4Uuvv7dWtCjbmVJcrskyk=
github.com/aws/smithy-go v1.13.4/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
@@ -1009,8 +1009,8 @@ github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQ
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.16.0/go.mod h1:N0A9sFdWzkw/Jy1lwoiB64F2+ugFZi987zRxcPez/wI=
github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
-github.com/jackc/pgx/v5 v5.1.0 h1:Z7pLKUb65HK6m18No8GGKT87K34NhIIEHa86rRdjxbU=
-github.com/jackc/pgx/v5 v5.1.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
+github.com/jackc/pgx/v5 v5.1.1 h1:pZD79K1SYv8wc2HmCQA6VdmRQi7/OtCfv9bM3WAXUYA=
+github.com/jackc/pgx/v5 v5.1.1/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
@@ -2292,8 +2292,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
-google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472 h1:kIfItBRE5gkUKpH4H5lNGciZbka1JrmRli3ArqrKFkA=
-google.golang.org/genproto v0.0.0-20221116193143-41c2ba794472/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
+google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6 h1:a2S6M0+660BgMNl++4JPlcAO/CjkqYItDEZwkoDQK7c=
+google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -2335,8 +2335,8 @@ google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
-google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
-google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
+google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U=
+google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
diff --git a/internal/dataprovider/user.go b/internal/dataprovider/user.go
index 96a58608..118337d5 100644
--- a/internal/dataprovider/user.go
+++ b/internal/dataprovider/user.go
@@ -489,8 +489,12 @@ func (u *User) GetPermissionsForPath(p string) []string {
// so the first match is the one we are interested to
for idx := range dirsForPath {
if perms, ok := u.Permissions[dirsForPath[idx]]; ok {
- permissions = perms
- break
+ return perms
+ }
+ for dir, perms := range u.Permissions {
+ if match, err := path.Match(dir, dirsForPath[idx]); err == nil && match {
+ return perms
+ }
}
}
return permissions
diff --git a/internal/ftpd/handler.go b/internal/ftpd/handler.go
index 017e7c01..216f4607 100644
--- a/internal/ftpd/handler.go
+++ b/internal/ftpd/handler.go
@@ -532,7 +532,7 @@ func (c *Connection) getListDirWithWildcards(dirName, pattern string) ([]os.File
}
func (c *Connection) isListDirWithWildcards(name string) bool {
- if strings.ContainsAny(name, "*?[]") {
+ if strings.ContainsAny(name, "*?[]^") {
lastCommand := c.clientContext.GetLastCommand()
return lastCommand == "LIST" || lastCommand == "NLST"
}
diff --git a/internal/sftpd/sftpd_test.go b/internal/sftpd/sftpd_test.go
index 35a7b18a..ca5aff29 100644
--- a/internal/sftpd/sftpd_test.go
+++ b/internal/sftpd/sftpd_test.go
@@ -182,7 +182,7 @@ func TestMain(m *testing.M) {
logFilePath = filepath.Join(configDir, "sftpgo_sftpd_test.log")
loginBannerFileName := "login_banner"
loginBannerFile := filepath.Join(configDir, loginBannerFileName)
- logger.InitLogger(logFilePath, 5, 1, 28, false, false, zerolog.DebugLevel)
+ logger.InitLogger(logFilePath, 10, 1, 28, false, false, zerolog.DebugLevel)
err := os.WriteFile(loginBannerFile, []byte("simple login banner\n"), os.ModePerm)
if err != nil {
logger.ErrorToConsole("error creating login banner: %v", err)
@@ -8182,6 +8182,32 @@ func TestUserPerms(t *testing.T) {
assert.True(t, user.HasPerm(dataprovider.PermDownload, "/p/1/test/file.dat"))
}
+func TestWildcardPermissions(t *testing.T) {
+ user := getTestUser(true)
+ user.Permissions = make(map[string][]string)
+ user.Permissions["/"] = []string{dataprovider.PermListItems}
+ user.Permissions["/p*"] = []string{dataprovider.PermDelete}
+ user.Permissions["/p/*"] = []string{dataprovider.PermDownload, dataprovider.PermUpload}
+ user.Permissions["/p/2"] = []string{dataprovider.PermCreateDirs}
+ user.Permissions["/pa"] = []string{dataprovider.PermChmod}
+ user.Permissions["/p/3/4"] = []string{dataprovider.PermChtimes}
+ assert.True(t, user.HasPerm(dataprovider.PermListItems, "/"))
+ assert.True(t, user.HasPerm(dataprovider.PermDelete, "/p1"))
+ assert.True(t, user.HasPerm(dataprovider.PermDelete, "/ppppp"))
+ assert.False(t, user.HasPerm(dataprovider.PermDelete, "/pa"))
+ assert.True(t, user.HasPerm(dataprovider.PermChmod, "/pa"))
+ assert.True(t, user.HasPerm(dataprovider.PermUpload, "/p/1"))
+ assert.True(t, user.HasPerm(dataprovider.PermUpload, "/p/p"))
+ assert.False(t, user.HasPerm(dataprovider.PermUpload, "/p/2"))
+ assert.True(t, user.HasPerm(dataprovider.PermDownload, "/p/3"))
+ assert.True(t, user.HasPerm(dataprovider.PermDownload, "/p/a/a/a"))
+ assert.False(t, user.HasPerm(dataprovider.PermDownload, "/p/3/4"))
+ assert.True(t, user.HasPerm(dataprovider.PermChtimes, "/p/3/4"))
+ assert.True(t, user.HasPerm(dataprovider.PermDelete, "/pb/a/a/a"))
+ assert.False(t, user.HasPerm(dataprovider.PermDelete, "/abc/a/a/a"))
+ assert.True(t, user.HasPerm(dataprovider.PermListItems, "/abc/a/a/a/b"))
+}
+
func TestFilterFilePatterns(t *testing.T) {
user := getTestUser(true)
pattern := sdk.PatternsFilter{
diff --git a/templates/webadmin/group.html b/templates/webadmin/group.html
index 090cf83f..084b1491 100644
--- a/templates/webadmin/group.html
+++ b/templates/webadmin/group.html
@@ -160,7 +160,7 @@ along with this program. If not, see