escape DN attribute values

This commit is contained in:
David Christofas
2022-07-06 15:16:43 +02:00
parent 41226deab7
commit 2707c2f4b4
5 changed files with 79 additions and 2 deletions

View File

@@ -0,0 +1,6 @@
Bugfix: Escape DN attribute value
Escaped the DN attribute value on creating users and groups.
https://github.com/owncloud/ocis/pull/4117

View File

@@ -5,6 +5,7 @@ import (
"errors"
"io/ioutil"
"os"
"strings"
"time"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
@@ -15,6 +16,20 @@ const (
caCheckSleep = 2
)
var (
dnEscaper = strings.NewReplacer(
"\\", "\\\\",
",", "\\,",
"+", "\\+",
`"`, `\\"`,
"<", "\\<",
">", "\\>",
";", "\\;",
"=", "\\=",
"\000", "\\\000",
)
)
func WaitForCA(log log.Logger, insecure bool, caCert string) error {
if !insecure && caCert != "" {
for i := 0; i < caCheckRetries; i++ {
@@ -38,3 +53,20 @@ func WaitForCA(log log.Logger, insecure bool, caCert string) error {
}
return nil
}
// EscapeDNAttributeValue escapes special characters in an attribute value as [described in RFC4514](https://datatracker.ietf.org/doc/html/rfc4514).
func EscapeDNAttributeValue(v string) string {
if v == "" {
return v
}
v = dnEscaper.Replace(v)
if strings.HasSuffix(v, " ") {
v = v[:len(v)-1] + "\\ "
}
if strings.HasPrefix(v, "#") || strings.HasPrefix(v, " ") {
v = "\\" + v
}
return v
}

View File

@@ -0,0 +1,13 @@
package ldap_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestLdap(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Ldap Suite")
}

View File

@@ -0,0 +1,25 @@
package ldap_test
import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/owncloud/ocis/v2/ocis-pkg/ldap"
)
var _ = Describe("ldap", func() {
DescribeTable("EscapeDNAttributeValue should escape special characters",
func(input, expected string) {
escaped := ldap.EscapeDNAttributeValue(input)
Expect(escaped).To(Equal(expected))
},
Entry("normal dn", "foobar", "foobar"),
Entry("including comma", "foo,bar", "foo\\,bar"),
Entry("including equals", "foo=bar", "foo\\=bar"),
Entry("beginning with number sign", "#foobar", "\\#foobar"),
Entry("beginning with space", " foobar", "\\ foobar"),
Entry("only one space", " ", "\\ "),
Entry("two spaces", " ", "\\ \\ "),
Entry("ending with space", "foobar ", "foobar\\ "),
Entry("containing multiple special chars", `f+o>o,b<a;r="\00"`, `f\+o\>o\,b\<a\;r\=\\"\\00\\"`),
)
})

View File

@@ -11,6 +11,7 @@ import (
"github.com/gofrs/uuid"
ldapdn "github.com/libregraph/idm/pkg/ldapdn"
libregraph "github.com/owncloud/libre-graph-api-go"
oldap "github.com/owncloud/ocis/v2/ocis-pkg/ldap"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/services/graph/pkg/config"
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
@@ -116,7 +117,7 @@ func (i *LDAP) CreateUser(ctx context.Context, user libregraph.User) (*libregrap
return nil, errReadOnly
}
ar := ldap.AddRequest{
DN: fmt.Sprintf("uid=%s,%s", *user.OnPremisesSamAccountName, i.userBaseDN),
DN: fmt.Sprintf("uid=%s,%s", oldap.EscapeDNAttributeValue(*user.OnPremisesSamAccountName), i.userBaseDN),
Attributes: []ldap.Attribute{
// inetOrgPerson requires "cn"
{
@@ -691,7 +692,7 @@ func (i *LDAP) CreateGroup(ctx context.Context, group libregraph.Group) (*libreg
return nil, errorcode.New(errorcode.NotAllowed, "server is configured read-only")
}
ar := ldap.AddRequest{
DN: fmt.Sprintf("cn=%s,%s", *group.DisplayName, i.groupBaseDN),
DN: fmt.Sprintf("cn=%s,%s", oldap.EscapeDNAttributeValue(*group.DisplayName), i.groupBaseDN),
Attributes: []ldap.Attribute{
{
Type: i.groupAttributeMap.name,