LDAP Config loading results in panic
Describe the bug
Attempting to use auth.ldap results in a panic on config load.
Steps to reproduce
Configure ldap, I don't think it actually matters if the server is up because maddy panics before then:
auth.ldap ldap_authdb {
urls ldap://localhost:389
bind unauth
base_dn "ou=entities,dc=netauth,dc=voidlinux,dc=org"
filter "(uid={username})"
}
Log files
panic: reflect.Set: value of type func(*ldap.Conn, string) error is not assignable to type func(*ldap.Conn) error
goroutine 1 [running]:
reflect.Value.assignTo({0xea0040, 0x106b708, 0x110}, {0x10111b2, 0xb}, 0xe8b820, 0x0)
reflect/value.go:2810 +0x2ad
reflect.Value.Set({0xe8b820, 0xc0000c1468, 0x27239101ce0f8203}, {0xea0040, 0x106b708, 0xc00029eb08})
reflect/value.go:1918 +0xec
github.com/foxcpp/maddy/framework/config.(*matcher).assign(0xec42c0, {0xea0040, 0x106b708})
github.com/foxcpp/maddy/framework/config/map.go:48 +0xf3
github.com/foxcpp/maddy/framework/config.(*Map).ProcessWith(0xc0000c5c00, 0xc00038b4e8, {{0xc0002656a0, 0x9}, {0xc00026a760, 0x1, 0x1}, {0xc0000ed800, 0x4, 0x4}, ...})
github.com/foxcpp/maddy/framework/config/map.go:625 +0x534
github.com/foxcpp/maddy/framework/config.(*Map).Process(...)
github.com/foxcpp/maddy/framework/config/map.go:587
github.com/foxcpp/maddy/internal/auth/ldap.(*Auth).Init(0xc0000c1440, 0xc0000c5c00)
github.com/foxcpp/maddy/internal/auth/ldap/ldap.go:73 +0x418
github.com/foxcpp/maddy/framework/module.GetInstance({0xc0002bccb1, 0xb})
github.com/foxcpp/maddy/framework/module/instances.go:91 +0x103
github.com/foxcpp/maddy/framework/config/module.ModuleFromNode({0x1002c34, 0x120}, {0xc00026a890, 0x49d1cc, 0xf69440}, {{0xc0002bcc68, 0x4}, {0xc00026a890, 0x1, 0x1}, ...}, ...)
github.com/foxcpp/maddy/framework/config/module/modconfig.go:120 +0x128
github.com/foxcpp/maddy/internal/auth.(*SASLAuth).AddProvider(0xc00025f680, 0xc0003d8900, {{0xc0002bcc68, 0x4}, {0xc00026a890, 0x1, 0x1}, {0x0, 0x0, 0x0}, ...})
github.com/foxcpp/maddy/internal/auth/sasl.go:111 +0xb4
github.com/foxcpp/maddy/internal/endpoint/smtp.(*Endpoint).setConfig.func1(0xc0003d8900, {{0xc0002bcc68, 0x4}, {0xc00026a890, 0x1, 0x1}, {0x0, 0x0, 0x0}, 0x0, ...})
github.com/foxcpp/maddy/internal/endpoint/smtp/smtp.go:242 +0x45
github.com/foxcpp/maddy/framework/config.(*Map).ProcessWith(0xc0003d8900, 0x0, {{0xc0002bcaf0, 0xa}, {0xc0002e9fa0, 0x2, 0x2}, {0xc0000ed980, 0x4, 0x4}, ...})
github.com/foxcpp/maddy/framework/config/map.go:607 +0x3c6
github.com/foxcpp/maddy/framework/config.(*Map).Process(...)
github.com/foxcpp/maddy/framework/config/map.go:587
github.com/foxcpp/maddy/internal/endpoint/smtp.(*Endpoint).setConfig(0xc00025f680, 0xc0003d8900)
github.com/foxcpp/maddy/internal/endpoint/smtp/smtp.go:275 +0x5d8
github.com/foxcpp/maddy/internal/endpoint/smtp.(*Endpoint).Init(0xc00025f680, 0xc0003e7560)
github.com/foxcpp/maddy/internal/endpoint/smtp/smtp.go:106 +0xe5
github.com/foxcpp/maddy.initModules(0xc00023fc50, {0xc00017afc0, 0x3, 0x525459}, {0xc000395800, 0x6, 0x7ffd380d88b1})
github.com/foxcpp/maddy/maddy.go:404 +0x15c
github.com/foxcpp/maddy.moduleMain({0xc00026e480, 0xc000010788, 0x7ffd380d88b1})
github.com/foxcpp/maddy/maddy.go:321 +0xa5
github.com/foxcpp/maddy.Run(0xc000224c00)
github.com/foxcpp/maddy/maddy.go:204 +0x5fa
github.com/urfave/cli/v2.(*Command).Run(0xc000256000, 0xc000224a40)
github.com/urfave/cli/[email protected]/command.go:169 +0x6be
github.com/urfave/cli/v2.(*App).RunContext(0xc00009f040, {0x117ac30, 0xc000040080}, {0xc000032080, 0x4, 0x4})
github.com/urfave/cli/[email protected]/app.go:341 +0x89c
github.com/urfave/cli/v2.(*App).Run(...)
github.com/urfave/cli/[email protected]/app.go:247
github.com/foxcpp/maddy/internal/cli.Run()
github.com/foxcpp/maddy/internal/cli/app.go:106 +0x17e
main.main()
github.com/foxcpp/maddy/cmd/maddy/main.go:28 +0x17
table.file: ignoring non-existent file: /etc/maddy/aliases
smtp: listening on tcp://0.0.0.0:25
panic: reflect.Set: value of type func(*ldap.Conn, string) error is not assignable to type func(*ldap.Conn) error
goroutine 1 [running]:
reflect.Value.assignTo({0xea0040, 0x106b708, 0x110}, {0x10111b2, 0xb}, 0xe8b820, 0x0)
reflect/value.go:2810 +0x2ad
reflect.Value.Set({0xe8b820, 0xc0000c1468, 0xa1ad4952c3cca225}, {0xea0040, 0x106b708, 0xc00029eb08})
reflect/value.go:1918 +0xec
github.com/foxcpp/maddy/framework/config.(*matcher).assign(0xec42c0, {0xea0040, 0x106b708})
github.com/foxcpp/maddy/framework/config/map.go:48 +0xf3
github.com/foxcpp/maddy/framework/config.(*Map).ProcessWith(0xc0000c5c00, 0xc00038b4e8, {{0xc0002656a0, 0x9}, {0xc00026a750, 0x1, 0x1}, {0xc0000ed800, 0x4, 0x4}, ...})
github.com/foxcpp/maddy/framework/config/map.go:625 +0x534
github.com/foxcpp/maddy/framework/config.(*Map).Process(...)
github.com/foxcpp/maddy/framework/config/map.go:587
github.com/foxcpp/maddy/internal/auth/ldap.(*Auth).Init(0xc0000c1440, 0xc0000c5c00)
github.com/foxcpp/maddy/internal/auth/ldap/ldap.go:73 +0x418
github.com/foxcpp/maddy/framework/module.GetInstance({0xc0002bccb1, 0xb})
github.com/foxcpp/maddy/framework/module/instances.go:91 +0x103
github.com/foxcpp/maddy/framework/config/module.ModuleFromNode({0x1002c34, 0x120}, {0xc00026a880, 0x49d1cc, 0xf69440}, {{0xc0002bcc68, 0x4}, {0xc00026a880, 0x1, 0x1}, ...}, ...)
github.com/foxcpp/maddy/framework/config/module/modconfig.go:120 +0x128
github.com/foxcpp/maddy/internal/auth.(*SASLAuth).AddProvider(0xc00025f7a0, 0xc0003d8900, {{0xc0002bcc68, 0x4}, {0xc00026a880, 0x1, 0x1}, {0x0, 0x0, 0x0}, ...})
github.com/foxcpp/maddy/internal/auth/sasl.go:111 +0xb4
github.com/foxcpp/maddy/internal/endpoint/smtp.(*Endpoint).setConfig.func1(0xc0003d8900, {{0xc0002bcc68, 0x4}, {0xc00026a880, 0x1, 0x1}, {0x0, 0x0, 0x0}, 0x0, ...})
github.com/foxcpp/maddy/internal/endpoint/smtp/smtp.go:242 +0x45
Configuration file
# ----------------------------------------------------------------------------
# Base variables
$(hostname) = {env:MADDY_HOSTNAME}
$(primary_domain) = {env:MADDY_DOMAIN}
$(local_domains) = $(primary_domain)
tls file /data/tls/fullchain.pem /data/tls/privkey.pem
# ----------------------------------------------------------------------------
# Local storage & authentication
auth.ldap ldap_authdb {
urls ldap://localhost:389
bind unauth
base_dn "ou=entities,dc=netauth,dc=voidlinux,dc=org"
filter "(uid={username})"
}
storage.imapsql local_mailboxes {
delivery_map email_localpart
driver sqlite3
dsn imapsql.db
}
# ----------------------------------------------------------------------------
# SMTP endpoints + message routing
hostname $(hostname)
table.chain local_rewrites {
optional_step regexp "(.+)\+(.+)@(.+)" "$1@$3"
optional_step static {
entry postmaster postmaster@$(primary_domain)
}
optional_step file /etc/maddy/aliases
}
msgpipeline local_routing {
destination postmaster $(local_domains) {
modify {
replace_rcpt &local_rewrites
}
deliver_to &local_mailboxes
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
smtp tcp://0.0.0.0:25 {
limits {
# Up to 20 msgs/sec across max. 10 SMTP connections.
all rate 20 1s
all concurrency 10
}
dmarc yes
check {
require_mx_record
dkim
spf
}
source $(local_domains) {
reject 501 5.1.8 "Use Submission for outgoing SMTP"
}
default_source {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.1.1 "User doesn't exist"
}
}
}
submission tls://0.0.0.0:465 tcp://0.0.0.0:587 {
limits {
# Up to 50 msgs/sec across any amount of SMTP connections.
all rate 50 1s
}
auth &ldap_authdb
source $(local_domains) {
check {
authorize_sender {
prepare_email &local_rewrites
user_to_email identity
}
}
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
modify {
dkim $(primary_domain) $(local_domains) default
}
deliver_to &remote_queue
}
}
default_source {
reject 501 5.1.8 "Non-local sender domain"
}
}
target.remote outbound_delivery {
limits {
# Up to 20 msgs/sec across max. 10 SMTP connections
# for each recipient domain.
destination rate 20 1s
destination concurrency 10
}
mx_auth {
dane
mtasts {
cache fs
fs_dir mtasts_cache/
}
local_policy {
min_tls_level encrypted
min_mx_level none
}
}
}
target.queue remote_queue {
target &outbound_delivery
autogenerated_msg_domain $(primary_domain)
bounce {
destination postmaster $(local_domains) {
deliver_to &local_routing
}
default_destination {
reject 550 5.0.0 "Refusing to send DSNs to non-local addresses"
}
}
}
# ----------------------------------------------------------------------------
# IMAP endpoints
imap tls://0.0.0.0:993 tcp://0.0.0.0:143 {
auth &ldap_authdb
storage &local_mailboxes
}
Environment information
- maddy version: 0.6.2 via docker.
Further testing has shown that the bind parsing is just broken. I have changed my config from bind unauth to not having the bind keyword present and things mostly work now. I am not really sure why this breaks, because reading the code nothing looks obviously off.
Mine is
auth.ldap ldap_authdb {
#debug on
urls ldaps://ldap.example.org:636
dn_template "cn={username},ou=users,dc=mail,dc=example,dc=org"
}
so it automatically tries to bind with the credentials the user provides.
@AlphaJack yes, I want to search though so that mailbox creation works (not that it does in my setup anyway with search, but I'm kind of chalking that up to auth_map/delivery_map appearing to be fundamentally broken.
@foxcpp Can you please release a 6.3 with this fix? The latest release is from July 2022
Fixed as of 0.7.