[SOLVED] Re: LMTP Post login script for acl_groups

lists at mlserv.org lists at mlserv.org
Thu Aug 29 15:34:57 EEST 2019



> Am 29.08.2019 um 11:58 schrieb R.N.S. via dovecot <dovecot at dovecot.org>:
> 
> 
> 
>> Am 29.08.2019 um 11:30 schrieb R.N.S. via dovecot <dovecot at dovecot.org>:
>> 
>> 
>> 
>>> Am 29.08.2019 um 11:23 schrieb Aki Tuomi via dovecot <dovecot at dovecot.org>:
>>> 
>>> 
>>> On 29.8.2019 12.18, R.N.S. via dovecot wrote:
>>>> 
>>>>> Am 28.08.2019 um 20:02 schrieb Aki Tuomi via dovecot <dovecot at dovecot.org>:
>>>>> 
>>>>> 
>>>>>> On 28/08/2019 21:01 R.N.S. via dovecot <dovecot at dovecot.org> wrote:
>>>>>> 
>>>>>> 
>>>>>>> Am 28.08.2019 um 19:46 schrieb Jakobus Schürz via dovecot <dovecot at dovecot.org>:
>>>>>>> 
>>>>>>> I think, i had the same problem as you.
>>>>>>> 
>>>>>>> When dovecot runs lmtp, no user is logged in, so there is no user from
>>>>>>> which you can get groups. So i think, my solution is (not really sure,
>>>>>>> if this is right, it's a long time ago, i played around) this transport
>>>>>>> in exim for local delivery
>>>>>>> 
>>>>>>> dovecot_delivery:             
>>>>>>> debug_print = "T: dovecot_delivery_pipe for $local_part@$domain
>>>>>>> translates to GET_LOCAL_MAIL"
>>>>>>> driver = pipe               
>>>>>>> command = /usr/lib/dovecot/deliver -d "GET_LOCAL_MAIL"
>>>>>>> message_prefix =
>>>>>>> message_suffix =
>>>>>>> delivery_date_add
>>>>>>> envelope_to_add             
>>>>>>> return_path_add             
>>>>>>> log_output
>>>>>>> user = MAILUSER
>>>>>>> group = MAILUSER
>>>>>>> 
>>>>>>> I have a really sophisticated setup with ldap... so GET_LOCAL_MAIL and
>>>>>>> MAILUSER are makros which get the email-adress and the mailuser for the
>>>>>>> receiving emailadress.
>>>>>>> 
>>>>>>> GET_LOCAL_MAIL could be $local_part@$domain
>>>>>>> MAILUSER is vmail in my setup, the user who owns all mailboxes
>>>>>>> 
>>>>>>> /usr/lib/dovecot/deliver is an alternative for the lmtp-delivery.
>>>>>> Unfortunately this way Postfix and Dovecot need to run on the same host.
>>>>>> 
>>>>>> I wonder, if this is a LMTP or Sieve issue. Maybe something can be done in sieve configuration to solve this?
>>>>>> 
>>>>>> Is there nobody from @Dovecot who could give some feedback :-) please :-)
>>>>>> 
>>>>>> Thanks
>>>>>> 
>>>>>> Christian
>>>>> It could be possible to solve this with auth lua script that would allow returning the acl groups as a string, instead of using post-login script.
>>>> I finally got it working with Lua.
>>>> 
>>>> Changes to the auth-ldap.conf.ext file:
>>>> --------------------------------------------------
>>>> userdb {
>>>> driver = ldap
>>>> args = /etc/dovecot/dovecot-ldap.conf.ext
>>>> 
>>>> # Fetch acl_groups from LDAP with the Lua userdb script
>>>> skip = never
>>>> result_success = continue
>>>> result_failure = return-fail
>>>> 
>>>> # Default fields can be used to specify defaults that LDAP may override
>>>> #default_fields = home=/home/virtual/%u
>>>> }
>>>> --------------------------------------------------
>>>> 
>>>> I created this auth-lua.conf.ext:
>>>> --------------------------------------------------
>>>> # https://wiki.dovecot.org/AuthDatabase/Lua
>>>> 
>>>> userdb {
>>>> driver = lua
>>>> args = file=/etc/dovecot/dovecot-auth-userdb.lua  blocking=yes
>>>> }
>>>> --------------------------------------------------
>>>> 
>>>> I added it in 10-auth.conf behind the LDAP auth include statement.
>>>> 
>>>> The Lua script looks like this:
>>>> --------------------------------------------------
>>>> require('io')
>>>> 
>>>> function auth_userdb_lookup(req)
>>>> local bindpwfile = "/etc/dovecot/ldap-auth-userdb.secret"
>>>> local base = "ou=people,ou=it,dc=roessner-net,dc=de"
>>>> local binddn = "cn=dovecot," .. base
>>>> 
>>>> local cmd = [=[
>>>>  /bin/sh -c "ldapsearch -LLL -ZZ -y $bindpwfile -xD $binddn -b $base '(rnsMSDovecotUser=$user)' rnsMSACLGroup | \
>>>>    grep rnsMSACLGroup | \
>>>>    awk -vORS=, '{ print \$2 }' | \
>>>>    sed 's/,$/\n/'"
>>>> ]=]
>>>> 
>>>> cmd = cmd:gsub('$(%w+)', { bindpwfile = bindpwfile })
>>>> cmd = cmd:gsub('$(%w+)', { binddn = binddn })
>>>> cmd = cmd:gsub('$(%w+)', { base = base })
>>>> cmd = cmd:gsub('$(%w+)', { user = req.user })
>>>> 
>>>> local handle = io.popen(cmd)
>>>> local acl_groups = handle:read("*a")
>>>> 
>>>> return dovecot.auth.USERDB_RESULT_OK, "acl_groups=" .. acl_groups
>>>> end
>>>> 
>>>> function script_init()
>>>> return 0
>>>> end
>>>> 
>>>> function script_deinit()
>>>> end
>>>> 
>>>> -- vim: expandtab ts=2 sw=2
>>>> --------------------------------------------------
>>>> 
>>>> And this works for me :-)
>>>> 
>>>> Many thanks
>>>> 
>>>> Christian
>>> 
>>> There really is no LDAP module for your LUA?
>> 
>> I was too early with success :-(
>> 
>> Even the doveadm acl debug command shows that I would have all rights, mails are insert into the INBOX :-(
>> 
>> ...
>> doveadm(lists at srvint.net): Info: User lists at srvint.net has rights: lookup read write write-seen write-deleted insert post expunge
>> doveadm(lists at srvint.net): Info: Mailbox found from dovecot-acl-list
>> doveadm(lists at srvint.net): Info: Mailbox is in public namespace
>> doveadm(lists at srvint.net): Info: Mailbox Public/Mailinglisten/Dovecot is visible in LIST
>> 
>> Why can't LMTP/Sieve insert the Mail to that place?
>> 
>> If I use a LDAP attribute with a comma separated list in the dovecot-ldap.conf.ext file, everything works. So what is different to the second Lua backend?
>> 
>> It is really a pain that acl_groups does not simply support multi values.
>> 
>> Maybe I will spend some more time for the Lua LDAP module, but for now, it is really frustrating.
> 
> Have been minor issues in the Lua script. I now will spend some time to dive into the Lua-LDAP module. For now, the posted solution works.
> 
> If I have a module that talks directly to LDAP, I will return later here and post the results.
> 
> Christian

This version uses lualdap:
--------------------------------------------------
require('io')
local ldap = require "lualdap"
assert(ldap)

-- Global LDAP settings
local uri = "ldap://db.roessner-net.de"
local cacertfile = "/etc/ssl/certs/rnscacert.pem"
local base = "ou=people,ou=it,dc=roessner-net,dc=de"
local binddn = "cn=dovecot," .. base
local bindpwfile = "/etc/dovecot/ldap-auth-userdb.secret"
local attrs = "rnsMSACLGroup"
local filter = "(rnsMSRecipientAddress=$user)"

function auth_userdb_lookup(req)

  -- read bind password
  local handle = io.open(bindpwfile)
  local password = handle:read("*all")
  handle:close()

  -- connect to LDAP
  local session, err = ldap.open_simple({
    uri = uri,
    who = binddn,
    password = password,
    starttls = true,
    cacertfile = cacertfile
  })
  assert(err == nil)
  assert(session)

  -- read acl_groups from LDAP
  local acl_groups = nil
  for dn, attribs in session:search{
    attrs = attrs,
    base = base,
    scope = "sub",
    filter = filter:gsub('$(%w+)', { user = req.user })
  } do
    for name, values in pairs(attribs) do
      if type(values) == "string" then
        acl_groups = values
      elseif type(values) == "table" then
        acl_groups = table.concat(values, ",")
      end
    end
  end

  dovecot.i_info("user=" .. req.user .. " acl_groups=" .. acl_groups)

  return dovecot.auth.USERDB_RESULT_OK, "acl_groups=" .. acl_groups
end

function script_init()
  return 0
end

function script_deinit()
end

-- vim: expandtab ts=2 sw=2
--------------------------------------------------

Have fun

Christian


More information about the dovecot mailing list