def list_policies(inst, basedn, log, args): log = log.getChild('list_policies') targetdn = args.DN[0] if args.json: result = {'type': 'list', 'items': []} else: result = "" # Verify target dn exists before getting started user_entry = Account(inst, args.DN[0]) if not user_entry.exists(): raise ValueError('The target entry dn does not exist') # User pwpolicy entry is under the container that is under the parent, # so we need to go one level up pwp_entries = PwPolicyEntries(inst, targetdn) for pwp_entry in pwp_entries.list(): dn_comps = ldap.dn.explode_dn(pwp_entry.get_attr_val_utf8_l('cn')) dn_comps.pop(0) entrydn = ",".join(dn_comps) policy_type = _get_policy_type(inst, entrydn) if args.json: result['items'].append([entrydn, policy_type]) else: result += "%s (%s)\n" % (entrydn, policy_type.lower()) if args.json: print(json.dumps(result)) else: print(result)
def get_pwpolicy_entry(self, dn): """Get a local password policy entry :param dn: Entry DN for the local pwpolicy :type dn: str :returns: PwPolicyEntry instance """ entry = Account(self._instance, dn) if not entry.exists(): raise ValueError( 'Can not get the password policy entry because the target dn does not exist' ) # Get the parent DN dn_comps = ldap.dn.explode_dn(entry.dn) dn_comps.pop(0) parentdn = ",".join(dn_comps) # Get the parent's policies pwp_entries = PwPolicyEntries(self._instance, parentdn) policies = pwp_entries.list() for policy in policies: dn_comps = ldap.dn.explode_dn(policy.get_attr_val_utf8_l('cn')) dn_comps.pop(0) pwp_dn = ",".join(dn_comps) if pwp_dn == dn.lower(): # This DN does have a policy associated with it return policy # Did not find a policy for this entry raise ValueError("No password policy was found for this entry")
def list_policies(inst, basedn, log, args): log = log.getChild('list_policies') if args.DN is None: # list all the password policies for all the backends targetdns = [] backends = Backends(inst).list() for backend in backends: targetdns.append(backend.get_suffix()) else: targetdns = [args.DN] if args.json: result = {'type': 'list', 'items': []} else: result = "" for targetdn in targetdns: # Verify target dn exists before getting started user_entry = Account(inst, targetdn) if not user_entry.exists(): raise ValueError('The target entry dn does not exist') # User pwpolicy entry is under the container that is under the parent, # so we need to go one level up pwp_entries = PwPolicyEntries(inst, targetdn) pwp_manager = PwPolicyManager(inst) attr_list = list(pwp_manager.arg_to_attr.values()) for pwp_entry in pwp_entries.list(): dn_comps = ldap.dn.explode_dn(pwp_entry.get_attr_val_utf8_l('cn')) dn_comps.pop(0) entrydn = ",".join(dn_comps) policy_type = _get_policy_type(inst, entrydn) all_attrs = pwp_entry.get_attrs_vals_utf8(attr_list) attrs = {k: v for k, v in all_attrs.items() if len(v) > 0} if args.json: result['items'].append( { "dn": pwp_entry.dn, "targetdn": entrydn, "pwp_type": policy_type, "basedn": pwp_entry.get_basedn(), "attrs": attrs } ) else: result += "%s (%s)\n" % (entrydn, policy_type.lower()) if args.json: print(json.dumps(result, indent=4)) else: print(result)
def create_subtree_policy(self, dn, properties): """Creates all entries which are needed for the subtree password policy :param dn: Entry DN for the subtree pwpolicy :type dn: str :param properties: A dict with password policy settings :type properties: dict :returns: PwPolicyEntry instance """ # Verify target dn exists before getting started subtree_entry = Account(self._instance, dn) if not subtree_entry.exists(): raise ValueError('Can not create subtree password policy because the target dn does not exist') # Create the pwp container if needed pwp_containers = nsContainers(self._instance, basedn=dn) pwp_container = pwp_containers.ensure_state(properties={'cn': 'nsPwPolicyContainer'}) # Create policy entry pwp_entry = None properties['cn'] = 'cn=nsPwPolicyEntry_subtree,%s' % dn pwp_entries = PwPolicyEntries(self._instance, pwp_container.dn) pwp_entry = pwp_entries.create(properties=properties) try: # The CoS template entry (nsPwTemplateEntry) that has the pwdpolicysubentry # value pointing to the above (nsPwPolicyEntry) entry cos_template = None cos_templates = CosTemplates(self._instance, pwp_container.dn) cos_template = cos_templates.create(properties={'cosPriority': '1', 'pwdpolicysubentry': pwp_entry.dn, 'cn': 'cn=nsPwTemplateEntry,%s' % dn}) # The CoS specification entry at the subtree level cos_pointer_defs = CosPointerDefinitions(self._instance, dn) cos_pointer_defs.create(properties={'cosAttribute': 'pwdpolicysubentry default operational', 'cosTemplateDn': cos_template.dn, 'cn': 'nsPwPolicy_CoS'}) except ldap.LDAPError as e: # Something went wrong, remove what we have done if pwp_entry is not None: pwp_entry.delete() if cos_template is not None: cos_template.delete() raise e # make sure that local policies are enabled self.set_global_policy({'nsslapd-pwpolicy-local': 'on'}) return pwp_entry
def create_user_policy(self, dn, properties): """Creates all entries which are needed for the user password policy :param dn: Entry DN for the subtree pwpolicy :type dn: str :param properties: A dict with password policy settings :type properties: dict :returns: PwPolicyEntry instance """ # Verify target dn exists before getting started user_entry = Account(self._instance, dn) if not user_entry.exists(): raise ValueError( 'Can not create user password policy because the target dn does not exist' ) dn_comps = ldap.dn.explode_dn(user_entry.dn) dn_comps.pop(0) parentdn = ",".join(dn_comps) # Create the pwp container if needed pwp_containers = nsContainers(self._instance, basedn=parentdn) pwp_container = pwp_containers.ensure_state( properties={'cn': 'nsPwPolicyContainer'}) # Create policy entry properties['cn'] = 'cn=nsPwPolicyEntry_user,%s' % dn pwp_entries = PwPolicyEntries(self._instance, pwp_container.dn) pwp_entry = pwp_entries.create(properties=properties) try: # Add policy to the entry user_entry.replace('pwdpolicysubentry', pwp_entry.dn) except ldap.LDAPError as e: # failure, undo what we have done pwp_entry.delete() raise e # make sure that local policies are enabled self.set_global_policy({'nsslapd-pwpolicy-local': 'on'}) return pwp_entry
def delete_local_policy(self, dn): """Delete a local password policy entry :param dn: Entry DN for the local pwpolicy :type dn: str """ subtree = False # Verify target dn exists, and has a policy entry = Account(self._instance, dn) if not entry.exists(): raise ValueError('The target entry dn does not exist') pwp_entry = self.get_pwpolicy_entry(entry.dn) # Subtree or user policy? if self.is_subtree_policy(entry.dn): parentdn = dn subtree = True else: dn_comps = ldap.dn.explode_dn(dn) dn_comps.pop(0) parentdn = ",".join(dn_comps) # Starting deleting the policy, ignore the parts that might already have been removed pwp_container = nsContainer(self._instance, 'cn=nsPwPolicyContainer,%s' % parentdn) if subtree: try: # Delete template cos_templates = CosTemplates(self._instance, pwp_container.dn) cos_template = cos_templates.get('cn=nsPwTemplateEntry,%s' % dn) cos_template.delete() except ldap.NO_SUCH_OBJECT: # Already deleted pass try: # Delete definition cos_pointer_def = CosPointerDefinition( self._instance, 'cn=nsPwPolicy_CoS,%s' % dn) cos_pointer_def.delete() except ldap.NO_SUCH_OBJECT: # Already deleted pass else: try: # Cleanup user entry entry.remove("pwdpolicysubentry", pwp_entry.dn) except ldap.NO_SUCH_ATTRIBUTE: # Policy already removed from user pass # Remove the local policy try: pwp_entry.delete() except ldap.NO_SUCH_OBJECT: # Already deleted pass try: pwp_container.delete() except (ldap.NOT_ALLOWED_ON_NONLEAF, ldap.NO_SUCH_OBJECT): # There are other policies still using this container, no problem pass