Skip to content

Commit

Permalink
lib/api: Allow BindDN to exclude any username formatting (fixes #8899) (
Browse files Browse the repository at this point in the history
#8900)

This allows a syncthing instance to be locked to exactly 1 user without
needing search capability on the LDAP instance.
  • Loading branch information
wrouesnel committed May 10, 2023
1 parent e136d11 commit b2fb2ef
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/api/api_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ func authLDAP(username string, password string, cfg config.LDAPConfiguration) bo

defer connection.Close()

err = connection.Bind(fmt.Sprintf(cfg.BindDN, username), password)
err = connection.Bind(ldapTemplateBindDN(cfg.BindDN, username), password)
if err != nil {
l.Warnln("LDAP Bind:", err)
return false
Expand Down Expand Up @@ -199,6 +199,15 @@ func authLDAP(username string, password string, cfg config.LDAPConfiguration) bo
return true
}

func ldapTemplateBindDN(bindDN string, username string) string {
// Check if formatting directives are included in the ldapTemplateBindDN - if so add username.
// (%%s is a literal %s - unlikely for LDAP, but easy to handle here).
if strings.Count(bindDN, "%s") != strings.Count(bindDN, "%%s") {
bindDN = fmt.Sprintf(bindDN, username)
}
return bindDN
}

// Convert an ISO-8859-1 encoded byte string to UTF-8. Works by the
// principle that ISO-8859-1 bytes are equivalent to unicode code points,
// that a rune slice is a list of code points, and that stringifying a slice
Expand Down
20 changes: 20 additions & 0 deletions lib/api/api_auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,23 @@ func TestStaticAuthPasswordFail(t *testing.T) {
t.Fatalf("should fail auth")
}
}

func TestAuthLDAPSendsCorrectBindDNWithTemplate(t *testing.T) {
t.Parallel()

templatedDn := ldapTemplateBindDN("cn=%s,dc=some,dc=example,dc=com", "username")
expectedDn := "cn=username,dc=some,dc=example,dc=com"
if expectedDn != templatedDn {
t.Fatalf("ldapTemplateBindDN should be %s != %s", expectedDn, templatedDn)
}
}

func TestAuthLDAPSendsCorrectBindDNWithNoTemplate(t *testing.T) {
t.Parallel()

templatedDn := ldapTemplateBindDN("cn=fixedusername,dc=some,dc=example,dc=com", "username")
expectedDn := "cn=fixedusername,dc=some,dc=example,dc=com"
if expectedDn != templatedDn {
t.Fatalf("ldapTemplateBindDN should be %s != %s", expectedDn, templatedDn)
}
}

0 comments on commit b2fb2ef

Please sign in to comment.