Motivation:
This thread helped me a lot to get started.
Because of this, here is a little write up on where I went with it:
Goal:
Use AD groups to give selective access in Icingaweb2 and use the same groups for Notifications.
Problem:
This is bad! As required by AGDLP, we have business groups as members of permission groups.
Impossible with only the director I would guess:
https://github.com/Icinga/icingaweb2-module-director/issues/2222
My solution for the moment:
https://github.com/Icinga/icingaweb2-module-fileshipper
And this quick hacked together script:
#!/usr/bin/env python3
# vim: set fileencoding=utf-8 ts=4 sw=4 sts=4 et :
from ldap3 import Server, Connection, ALL, NTLM
from ldap3.utils.conv import escape_filter_chars
import json
import sys
server = Server('ADSERVER', use_ssl=True, get_info=ALL)
def get_user_groups(dn):
with Connection(server, user="BINDUSER", password="BINDPW", authentication=NTLM) as conn:
dn = escape_filter_chars(dn)
conn.search(
search_base='SEARCHBASE',
search_filter='(member:1.2.840.113556.1.4.1941:=%s)' % dn,)
return conn.entries
with Connection(server, user="BINDUSER", password="BINDPW", authentication=NTLM) as conn:
conn.search(
search_base='SEARCHBASE',
search_filter='\
(&\
(memberOf:1.2.840.113556.1.4.1941:=DNOFMAINGROUP)\
(!(userAccountControl:1.2.840.113556.1.4.803:=2))\
(mail=*)\
(objectClass=user)\
)',
attributes=[
'SamAccountName',
'displayName',
'mail',
]
)
#print(conn.entries[0].entry_dn)
icinga_users = []
for user in conn.entries:
user_json = user.entry_to_json()
user_dict = json.loads(user_json)
user_dict.update(user_dict['attributes'])
del user_dict['attributes']
user_dict['groups'] = []
#print(user_dict)
groups = get_user_groups(user.entry_dn)
for group in groups:
group_json = group.entry_to_json()
group_dict = json.loads(group_json)
#print(group_dict)
user_dict['groups'].append(group_dict['dn'])
#print(json.dumps(user_dict, indent=4, sort_keys=True))
icinga_users.append(user_dict)
#break
#print(json.dumps(icinga_users, indent=4, sort_keys=True))
with open('icinga_users.json', 'w') as outfile:
json.dump(icinga_users, outfile)
Replace the following with your values:
- ADSERVER
- BINDUSER
- BINDPW
- DNOFMAINGROUP - I had to put all my icinga permisson groups in to one group - this is the one to rule them all
Next some cleanup. My Icingaweb2 permission groups have a ICT_Icinga_P prefix.
Excerpt from Basket:
"ImportSource": {
"Json from icinga_aduser.py": {
"description": null,
"key_column": "sAMAccountName",
"modifiers": [
{
"description": null,
"priority": "1",
"property_name": "sAMAccountName",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierJoin",
"settings": {
"glue": ""
},
"target_property": null
},
{
"description": null,
"priority": "2",
"property_name": "displayName",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierJoin",
"settings": {
"glue": ""
},
"target_property": null
},
{
"description": null,
"priority": "3",
"property_name": "groups",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierArrayFilter",
"settings": {
"filter_method": "wildcard",
"filter_string": "*ICT_P_Icinga*",
"policy": "keep",
"when_empty": "empty_array"
},
"target_property": null
},
{
"description": null,
"priority": "4",
"property_name": "groups",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierRegexReplace",
"settings": {
"pattern": "\/^cn=(.+?),ou=.*\/i",
"replacement": "\\1"
},
"target_property": null
},
{
"description": null,
"priority": "5",
"property_name": "groups",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierRegexReplace",
"settings": {
"pattern": "\/^ICT_P_Icinga_(.+?)$\/i",
"replacement": "\\1"
},
"target_property": null
},
{
"description": null,
"priority": "6",
"property_name": "groups",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierArrayFilter",
"settings": {
"filter_method": "wildcard",
"filter_string": "ICT_P_Icinga",
"policy": "reject",
"when_empty": "empty_array"
},
"target_property": null
},
{
"description": null,
"priority": "7",
"property_name": "mail",
"provider_class": "Icinga\\Module\\Director\\PropertyModifier\\PropertyModifierJoin",
"settings": {
"glue": ""
},
"target_property": null
}
],
"originalId": "6",
"provider_class": "Icinga\\Module\\Fileshipper\\ProvidedHook\\Director\\ImportSource",
"settings": {
"basedir": "\/var\/cache\/icinga_aduser",
"file_format": "json",
"file_name": "icinga_users.json"
},
"source_name": "Json from icinga_aduser.py"
},
Groups are easy and and don’t requre a external script The use of:
(&(memberOf:1.2.840.113556.1.4.1941:=DNOFMAINGROUP)(objectClass=group))
in the disector source ldap query was enough for me. The cleanup details are left as excercise to the reader…