foxcpp / maddy

✉️ Composable all-in-one mail server.
https://maddy.email
GNU General Public License v3.0
5.07k stars 244 forks source link

LDAP Config loading results in panic #529

Closed the-maldridge closed 9 months ago

the-maldridge commented 2 years ago

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/v2@v2.10.2/command.go:169 +0x6be
github.com/urfave/cli/v2.(*App).RunContext(0xc00009f040, {0x117ac30, 0xc000040080}, {0xc000032080, 0x4, 0x4})
    github.com/urfave/cli/v2@v2.10.2/app.go:341 +0x89c
github.com/urfave/cli/v2.(*App).Run(...)
    github.com/urfave/cli/v2@v2.10.2/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

the-maldridge commented 2 years ago

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.

AlphaJack commented 2 years ago

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.

the-maldridge commented 2 years ago

@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.

AlphaJack commented 1 year ago

@foxcpp Can you please release a 6.3 with this fix? The latest release is from July 2022

foxcpp commented 9 months ago

Fixed as of 0.7.