This commit is contained in:
Kostas Mparmparousis 2022-01-03 21:06:35 +02:00 committed by GitHub
commit 9cb05d1ae3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 14 deletions

View file

@ -0,0 +1,39 @@
# Configure PDA user privileges based on LDAP Attributes
Provisioning the roles and the associations of a user based on an attribute in his object, is a very useful practice for a variety of reasons, and can be implemented across multiple authentication providers for PDA. Below we demonstrate how to enable and configure Roles&Associations Provisioning during LDAP authentication.
The allowed syntax for records inside the attribute of the user's object is:
```text.
if PDA-Role∈[Administrator, Operator]:
syntax:=prefix:"powerdns-admin":PDA-Role
else:
syntax:=prefix:"powerdns-admin":PDA-Role:<domain>:<account>
where prefix is given by an admin of PDA in the configurable field "ADVANCE:Urn prefix".
i.e. some valid urn values could be:
urn:yourNID:yourOrganization:powerdns-admin:Administrator
urn:yourNID:yourOrganization:powerdns-admin:User:example.com (supposing there is a domain in the local db called "example.com")
urn:yourNID:yourOrganization:powerdns-admin:User:example.com:examplenet (supposing there is an account in the local db called "examplenet")
urn:yourNID:yourOrganization:powerdns-admin:User::examplenet
```
Note: To use Roles&Associations Provisioning in its fullest potential, the domains and the accounts provided in the entries must already exist, or else entries with no match in the local db will be skipped.
In order to keep users' privileges in-sync between the PDA's database and the LDAP, when no valid "powerdns-admin" values are found for the logged-in user, PDA will purge all privileges from the local database for this user. To avoid unintentional wipe outs of existing PDA privileges especially when admins enable this feature for the first time, the option "Purge Roles if empty" is also available. If toggled on, LDAP/OIDC entries that have no valid "powerdns-admin" records to their object's attribute, will lose all their associations with any domain or account, also reverting to a PDA-User in the process, despite their current role in the local db. If toggled off, in the same scenario they get to keep their existing associations and their current PDA-Role.
How to configure LDAP Roles Autoprovisioning:
1) Login as an admin to PowerDNS Admin.
2) Go to Settings --> Authentication.
3) Under Authentication, select LDAP.
4) Disable Group Security, if enabled.
5) Click the Radio Button for Roles Autoprovisioning.
6) Fill in the required info:
* Role Provisioning field - your_LDAP_Field.
* Urn prefix - your_URN_Prefix.
7) Enable Purge Roles If Empty, if you so wish, and click confirm when the prompt appears.
8) Click Save.
<a href="https://ibb.co/189yxmB"><img src="https://i.ibb.co/yW8vJQK/Screenshot-2021-09-13-at-13-39-33-Authentication-Settings-Power-DNS-Admin.png" alt="Screenshot-Authentication-Settings-Power-DNS-Admin" border="0"></a>

View file

@ -605,7 +605,7 @@ class User(db.Model):
return False
def set_role(self, role_name):
role = Role.query.filter(Role.name == role_name).first()
role = Role.query.filter(Role.name == role_name.capitalize()).first()
if role:
user = User.query.filter(User.username == self.username).first()
user.role_id = role.id
@ -676,12 +676,12 @@ class User(db.Model):
entitlements= getCorrectEntitlements(Entitlements)
if len(entitlements)!=0:
self.revoke_privilege(True)
role="user"
for entitlement in entitlements:
arguments=entitlement.split(':')
entArgs=arguments[arguments.index('powerdns-admin')+1:]
role= entArgs[0]
self.set_role(role)
if (role=="User") and len(entArgs)>1:
role= self.get_role(role,entArgs[0].lower())
if (role=="user") and len(entArgs)>1:
current_domains=getUserInfo(self.get_user_domains())
current_accounts=getUserInfo(self.get_accounts())
domain=entArgs[1]
@ -689,6 +689,14 @@ class User(db.Model):
if len(entArgs)>2:
account=entArgs[2]
self.addMissingAccount(account, current_accounts)
self.set_role(role)
def get_role(self, previousRole, newRole):
dict = { "user": 1, "operator" : 2, "administrator" : 3}
if (dict[newRole] > dict[previousRole]):
return newRole
else:
return previousRole
def addMissingDomain(self, autoprovision_domain, current_domains):
"""
@ -742,7 +750,7 @@ def getCorrectEntitlements(Entitlements):
continue
entArgs=arguments[arguments.index('powerdns-admin')+1:]
role=entArgs[0]
role=entArgs[0].lower()
roles= Role.query.all()
role_names=get_role_names(roles)
@ -752,7 +760,7 @@ def getCorrectEntitlements(Entitlements):
continue
if len(entArgs)>1:
if (role!="User"):
if (role!="user"):
e="Too many arguments for Admin or Operator"
current_app.logger.warning("Cannot apply autoprovisioning on user: {}".format(e))
continue
@ -797,7 +805,7 @@ def get_role_names(roles):
"""
roles_list=[]
for role in roles:
roles_list.append(role.name)
roles_list.append(role.name.lower())
return roles_list
def getUserInfo(DomainsOrAccounts):

View file

@ -210,7 +210,7 @@
</div>
</div>
<div class="form-group">
<label for="autoprovisioning_attribute">Roles provisioning field</label>
<label for="autoprovisioning_attribute">Roles provisioning attribute</label>
<input type="text" class="form-control" name="autoprovisioning_attribute" id="autoprovisioning_attribute" placeholder="e.g. eduPersonEntitlement" data-error=" Please input field responsible for autoprovisioning" value="{{ SETTING.get('autoprovisioning_attribute') }}">
<span class="help-block with-errors"></span>
</div>
@ -310,22 +310,41 @@
</ul>
</dd>
<dt>ADVANCE</dt>
<dd> Provision PDA user privileges based on LDAP Object Attributes. Alternative to Group Security Role Management.
<dd> Provision PDA user privileges based on a single attribute with URN values. Alternative to Group Security Role Management.
<ul>
<li>
Roles Autoprovisioning - If toggled on, the PDA Role and the associations of users found in the local db, will be instantly updated from the LDAP server every time they log in.
Roles Autoprovisioning - If toggled on, roles & associations of the PDA user will be determined based on the URN value(s) of an attribute in the user's LDAP object.
</li>
<li>
Roles provisioning field - The attribute in the ldap server populated by the urn values where PDA will look for a new Role and/or new associations to domains/accounts.
Roles provisioning attribute - The LDAP attribute where PDA will look for roles and/or associations to domains/accounts, each time the user logs in.<br>
eg. <i>eduPersonEntitlement</i><br>
Some <b>examples</b> of the URN value inside the provisioning attribute are:
<ul>
<li>
<i>urn:mace:organization.com:powerdns-admin:Administrator</i>, to set user as Administrator.
</li>
<li>
<i>urn:mace:organization.com:powerdns-admin:User:example.com</i>, to give user access to domain <i>example.com</i>.
</li>
<li>
<i>urn:mace:organization.com:powerdns-admin:User:example.com:example.net</i>, to give user access to domain <i>example.com</i> and add them to account <i>example.net</i>.
</li>
<li>
<i>urn:mace:organization.com:powerdns-admin:User::example.net</i>, to add user to account <i>example.net</i>.
</li>
(supposing <i>example.com</i>, <i>example.net</i> exist.)
</ul>
</li>
<li>
Urn prefix - The prefix used before the static keyword "powerdns-admin" for your entitlements in the ldap server. Must comply with RFC no.8141.
Urn prefix - The <i>urn:mace:organization.com</i> prefix referenced <i>above</i> that is used for your entitlements in the LDAP server.
</li>
<li>
Purge Roles If Empty - If toggled on, ldap entries that have no valid "powerdns-admin" records to their autoprovisioning field, will lose all their associations with any domain or account, also reverting to a User in the process, despite their current role in the local db.<br> If toggled off, in the same scenario they get to keep their existing associations and their current Role.
Purge Roles If Empty - If toggled <b>on</b>, LDAP entries that have no valid "powerdns-admin" records to their autoprovisioning field,
will <b>lose <u>all</u> their associations</b> with any domain or account, <b>also reverting to a User</b> in the process.<br>
If toggled <b>off</b>, in the same scenario they get to <b>keep their existing associations</b> and their current <b>Role</b>.
</li>
</ul>
For further information visit the <a href="https://github.com/PowerDNS-Admin/PowerDNS-Admin/blob/master/docs/Autoprovision_LDAP.md">LDAP Autoprovisioning wiki</a>
</dd>
</dl>
</div>