Signed-off-by: Georg <georg@lysergic.dev>

Init

- Config values for LDAP connectivity
- First LDAP read operations
This commit is contained in:
Georg Pfuetzenreuter 2021-08-24 15:32:05 +02:00
parent 6c5c9a989f
commit 1370ca690c
Signed by: Georg
GPG Key ID: 1DAF57F49F8E8F22
6 changed files with 153 additions and 1 deletions

View File

@ -1 +1,13 @@
### EgoServ-LDAP
This is in a very early development stage, and so is the upstream EgoServ plugin.
Goals:
- Extend EgoServ to sync user details and modifications with an external backend (LDAP)
- Extend EgoServ to modify user attributes beyond IRC
- Make EgoServ attractive to federated environments
- Allow for easier permission management through LDAP group assignments
----
### Original README.md:
Suite of tools to help Network Operators run their ErgoIRCd nets

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -52,5 +52,59 @@ EgoServ = conf.registerPlugin('EgoServ')
# conf.registerGlobalValue(EgoServ, 'someConfigVariableName',
# registry.Boolean(False, _("""Help for someConfigVariableName.""")))
conf.registerGroup(EgoServ, 'ldap')
conf.registerGlobalValue(EgoServ.ldap, 'host',
registry.String('',
"""
LDAP server URI to connect to.
Example: ` ldaps://example.com:636 `
Plain LDAP is not supported.
"""
, private=True
))
conf.registerGlobalValue(EgoServ.ldap, 'secure',
registry.Boolean('true',
"""
true: Strict TLS certificate checking
false: Certificates will be COMPLETELY ignored
Please keep this `true` in any environment that is not a local test instance.
If you don't have a working CA in your production LDAP infrastructure, unload this plugin.
"""
, private=True
))
conf.registerGlobalValue(EgoServ.ldap, 'basedn',
registry.String('',
"""
Base DN for all queries
"""
, private=True
))
conf.registerGlobalValue(EgoServ.ldap, 'binddn',
registry.String('',
"""
Unprivileged DN to bind to.
Ensure the ACIs are correct.
"""
, private=True
))
conf.registerGlobalValue(EgoServ.ldap, 'bindpw',
registry.String('',
"""
Password for the DN to bind to.
"""
, private=True
))
conf.registerGroup(EgoServ, 'groups')
conf.registerGlobalValue(EgoServ.groups, 'admins',
registry.String('',
"""
Group DN to grant the highest privileges to.
Only tested with ` CN= `.
"""
, private=True
))
# vim:set shiftwidth=4 tabstop=4 expandtab textwidth=79:

View File

@ -28,6 +28,7 @@
###
import ldap
from supybot import utils, plugins, ircutils, callbacks, irclib, ircmsgs, conf, world, log
from supybot.commands import *
try:
@ -51,6 +52,7 @@ class EgoServ(callbacks.Plugin):
# OPER
# This should check if it has OPER right away
# PERMS
# This is designed to be a single network ErgoIRCd administrative bot
# So maybe I just set default perms to owner!
@ -93,11 +95,53 @@ class EgoServ(callbacks.Plugin):
1: No new connections except from localhost or other trusted IPs
"""
arg = []
arg.append(level)
irc.sendMsg(msg=ircmsgs.IrcMsg(command='DEFCON', args=arg))
irc.replySuccess(f'Setting DEFCON level to {arg}! Good Luck!')
# QUERY
@wrap(['nick'])
def query(self, irc, msg, args, nick):
"""<nick>
Dumps shit.
"""
arg = [nick]
searchFilter = "(&(uid=" + nick + "*)(objectClass=nsPerson))"
searchAttribute = ["uid","uidNumber","nsAccountLock"]
searchScope = ldap.SCOPE_SUBTREE
host = self.registryValue('ldap.host')
binddn = self.registryValue('ldap.binddn')
pw = self.registryValue('ldap.bindpw')
basedn = self.registryValue('ldap.basedn')
secure = self.registryValue('ldap.secure')
if secure == False:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
else:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
l = ldap.initialize(host)
try:
ldap.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
l.protocol_version = ldap.VERSION3
l.simple_bind_s(binddn, pw)
except ldap.INVALID_CREDENTIALS:
print("Invalid LDAP credentials")
irc.reply("Internal error.")
except ldap.LDAPError:
print(ldap.LDAPError())
irc.reply("Error output sent to console.")
try:
ldap_result_id = l.search(basedn, searchScope, searchFilter, searchAttribute)
result_set = []
res = l.search_s(basedn, searchScope, searchFilter, searchAttribute)
print(res)
irc.reply(res)
except ldap.LDAPError:
print(ldap.LDAPError)
irc.reply("Error output sent to console.")
l.unbind_s()
# KILL
@wrap(['nick', optional('something')])
@ -287,8 +331,50 @@ class EgoServ(callbacks.Plugin):
sets a <nick>'s <vhost>. <vhost> must be in the format 'hello.world'
"""
arg = [nick]
searchFilter = "(&(uid=" + nick + "*)(objectClass=nsPerson))"
nickdn = "CN=" + nick + ",ou=lab_users,dc=lab,dc=local"
searchAttribute = ["uid"]
searchScope = ldap.SCOPE_SUBTREE
host = self.registryValue('ldap.host')
binddn = self.registryValue('ldap.binddn')
pw = self.registryValue('ldap.bindpw')
basedn = self.registryValue('ldap.basedn')
secure = self.registryValue('ldap.secure')
attr_vhost = 'displayName'
if secure == False:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
else:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
l = ldap.initialize(host)
try:
ldap.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
l.protocol_version = ldap.VERSION3
l.simple_bind_s(binddn, pw)
except ldap.INVALID_CREDENTIALS:
print("Invalid LDAP credentials")
irc.reply("Internal error.")
except ldap.LDAPError:
print(ldap.LDAPError())
irc.reply("Error output sent to console.")
try:
#this is not yet operational
#attrmod = [( ldap.MOD_REPLACE, attr_vhost, vhost)]
l.modify_s(nickdn, [( ldap.MOD_REPLACE, attr_vhost, vhost)])
print("Modifying " + nickdn + ": setting " + attr_vhost + " to" + vhost)
irc.reply("Attribute updated.")
except ldap.LDAPError:
print(ldap.LDAPError)
irc.reply("Error output sent to console.")
l.unbind_s()
label = ircutils.makeLabel()
irc.queueMsg(ircmsgs.IrcMsg(command='OPER', args=['coffee', '1234567890']))
arg = ['SET']
arg.append(nick)
arg.append(vhost)