forked from AkkomaGang/akkoma
Support LDAP method start_tls
This commit is contained in:
parent
88a672fe88
commit
9338f061a3
3 changed files with 49 additions and 16 deletions
|
@ -361,6 +361,8 @@
|
||||||
port: String.to_integer(System.get_env("LDAP_PORT") || "389"),
|
port: String.to_integer(System.get_env("LDAP_PORT") || "389"),
|
||||||
ssl: System.get_env("LDAP_SSL") == "true",
|
ssl: System.get_env("LDAP_SSL") == "true",
|
||||||
sslopts: [],
|
sslopts: [],
|
||||||
|
tls: System.get_env("LDAP_TLS") == "true",
|
||||||
|
tlsopts: [],
|
||||||
base: System.get_env("LDAP_BASE") || "dc=example,dc=com",
|
base: System.get_env("LDAP_BASE") || "dc=example,dc=com",
|
||||||
uid: System.get_env("LDAP_UID") || "cn"
|
uid: System.get_env("LDAP_UID") || "cn"
|
||||||
|
|
||||||
|
|
|
@ -329,13 +329,21 @@ config :auto_linker,
|
||||||
|
|
||||||
## :ldap
|
## :ldap
|
||||||
|
|
||||||
|
Use LDAP for user authentication. When a user logs in to the Pleroma
|
||||||
|
instance, the name and password will be verified by trying to authenticate
|
||||||
|
(bind) to an LDAP server. If a user exists in the LDAP directory but there
|
||||||
|
is no account with the same name yet on the Pleroma instance then a new
|
||||||
|
Pleroma account will be created with the same name as the LDAP user name.
|
||||||
|
|
||||||
* `enabled`: enables LDAP authentication
|
* `enabled`: enables LDAP authentication
|
||||||
* `host`: LDAP server hostname
|
* `host`: LDAP server hostname
|
||||||
* `port`: LDAP port, e.g. 389 or 636
|
* `port`: LDAP port, e.g. 389 or 636
|
||||||
* `ssl`: true to use SSL
|
* `ssl`: true to use SSL, usually implies the port 636
|
||||||
* `sslopts`: additional SSL options
|
* `sslopts`: additional SSL options
|
||||||
|
* `tls`: true to start TLS, usually implies the port 389
|
||||||
|
* `tlsopts`: additional TLS options
|
||||||
* `base`: LDAP base, e.g. "dc=example,dc=com"
|
* `base`: LDAP base, e.g. "dc=example,dc=com"
|
||||||
* `uid`: attribute type to authenticate the user, e.g. when "cn", the filter will be "cn=username,base"
|
* `uid`: LDAP attribute name to authenticate the user, e.g. when "cn", the filter will be "cn=username,base"
|
||||||
|
|
||||||
## Pleroma.Web.Auth.Authenticator
|
## Pleroma.Web.Auth.Authenticator
|
||||||
|
|
||||||
|
|
|
@ -60,22 +60,23 @@ defp ldap_user(name, password) do
|
||||||
case :eldap.open([to_charlist(host)], options) do
|
case :eldap.open([to_charlist(host)], options) do
|
||||||
{:ok, connection} ->
|
{:ok, connection} ->
|
||||||
try do
|
try do
|
||||||
uid = Keyword.get(ldap, :uid, "cn")
|
if Keyword.get(ldap, :tls, false) do
|
||||||
base = Keyword.get(ldap, :base)
|
:application.ensure_all_started(:ssl)
|
||||||
|
|
||||||
case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do
|
case :eldap.start_tls(
|
||||||
:ok ->
|
connection,
|
||||||
case User.get_by_nickname_or_email(name) do
|
Keyword.get(ldap, :tlsopts, []),
|
||||||
%User{} = user ->
|
@connection_timeout
|
||||||
user
|
) do
|
||||||
|
:ok ->
|
||||||
|
:ok
|
||||||
|
|
||||||
_ ->
|
error ->
|
||||||
register_user(connection, base, uid, name, password)
|
Logger.error("Could not start TLS: #{inspect(error)}")
|
||||||
end
|
end
|
||||||
|
|
||||||
error ->
|
|
||||||
error
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
bind_user(connection, ldap, name, password)
|
||||||
after
|
after
|
||||||
:eldap.close(connection)
|
:eldap.close(connection)
|
||||||
end
|
end
|
||||||
|
@ -86,11 +87,31 @@ defp ldap_user(name, password) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp bind_user(connection, ldap, name, password) do
|
||||||
|
uid = Keyword.get(ldap, :uid, "cn")
|
||||||
|
base = Keyword.get(ldap, :base)
|
||||||
|
|
||||||
|
case :eldap.simple_bind(connection, "#{uid}=#{name},#{base}", password) do
|
||||||
|
:ok ->
|
||||||
|
case User.get_by_nickname_or_email(name) do
|
||||||
|
%User{} = user ->
|
||||||
|
user
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
register_user(connection, base, uid, name, password)
|
||||||
|
end
|
||||||
|
|
||||||
|
error ->
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp register_user(connection, base, uid, name, password) do
|
defp register_user(connection, base, uid, name, password) do
|
||||||
case :eldap.search(connection, [
|
case :eldap.search(connection, [
|
||||||
{:base, to_charlist(base)},
|
{:base, to_charlist(base)},
|
||||||
{:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))},
|
{:filter, :eldap.equalityMatch(to_charlist(uid), to_charlist(name))},
|
||||||
{:scope, :eldap.wholeSubtree()},
|
{:scope, :eldap.wholeSubtree()},
|
||||||
|
{:attributes, ['mail', 'email']},
|
||||||
{:timeout, @search_timeout}
|
{:timeout, @search_timeout}
|
||||||
]) do
|
]) do
|
||||||
{:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} ->
|
{:ok, {:eldap_search_result, [{:eldap_entry, _, attributes}], _}} ->
|
||||||
|
@ -110,7 +131,9 @@ defp register_user(connection, base, uid, name, password) do
|
||||||
error -> error
|
error -> error
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
_ -> {:error, :ldap_registration_missing_attributes}
|
_ ->
|
||||||
|
Logger.error("Could not find LDAP attribute mail: #{inspect(attributes)}")
|
||||||
|
{:error, :ldap_registration_missing_attributes}
|
||||||
end
|
end
|
||||||
|
|
||||||
error ->
|
error ->
|
||||||
|
|
Loading…
Reference in a new issue