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 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', # conf.registerGlobalValue(EgoServ, 'someConfigVariableName',
# registry.Boolean(False, _("""Help for 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: # 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 import utils, plugins, ircutils, callbacks, irclib, ircmsgs, conf, world, log
from supybot.commands import * from supybot.commands import *
try: try:
@ -51,6 +52,7 @@ class EgoServ(callbacks.Plugin):
# OPER # OPER
# This should check if it has OPER right away # This should check if it has OPER right away
# PERMS # PERMS
# This is designed to be a single network ErgoIRCd administrative bot # This is designed to be a single network ErgoIRCd administrative bot
# So maybe I just set default perms to owner! # 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 1: No new connections except from localhost or other trusted IPs
""" """
arg = [] arg = []
arg.append(level) arg.append(level)
irc.sendMsg(msg=ircmsgs.IrcMsg(command='DEFCON', args=arg)) irc.sendMsg(msg=ircmsgs.IrcMsg(command='DEFCON', args=arg))
irc.replySuccess(f'Setting DEFCON level to {arg}! Good Luck!') 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 # KILL
@wrap(['nick', optional('something')]) @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' 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() label = ircutils.makeLabel()
irc.queueMsg(ircmsgs.IrcMsg(command='OPER', args=['coffee', '1234567890']))
arg = ['SET'] arg = ['SET']
arg.append(nick) arg.append(nick)
arg.append(vhost) arg.append(vhost)