def compare(self, ad_user, cb_user): """ Compare Cerebrum user with the AD attributes listed in self.sync_attrs and decide if AD should be updated or not. @param ad_user: attributes for a user fetched from AD @type ad_user: dict @param cb_user: CerebrumUser instance @type cb_user: CerebrumUser """ cb_attrs = cb_user.ad_attrs dn = ad_user["distinguishedName"] # Check if user is quarantined. If so, disable if cb_attrs["ACCOUNTDISABLE"] and not ad_user["ACCOUNTDISABLE"]: self.disable_user(dn) # Check if user has correct OU. If not, move user. if self.get_ou(dn) != cb_user.ou: self.move_user(dn, cb_user.ou) # Object is moved, so dn must be corrected dn = dn.replace(self.get_ou(dn), cb_user.ou) # Sync attributes for attr in self.sync_attrs: # Now, compare values from AD and Cerebrum cb_attr = cb_attrs.get(attr) ad_attr = ad_user.get(attr) if cb_attr and ad_attr: # value both in ad and cerebrum => compare result = self.attr_cmp(cb_attr, ad_attr) # Special case: Change name of AD user object? if attr == "cn" and result: cb_cn = "CN=" + cb_attrs["cn"] self.rename_object(dn, self.get_ou(dn), cb_cn) dn = "%s,%s" % (cb_cn, self.get_ou(dn)) # Normal cases elif result: self.logger.debug("Changing attr %s from %s to %s", attr, unicode2str(ad_attr), unicode2str(cb_attr)) cb_user.add_change(attr, result) elif cb_attr: # attribute is not in AD and cerebrum value is set => update AD cb_user.add_change(attr, cb_attr) elif ad_attr: # value only in ad => delete value in ad # TBD: is this correct behavior? cb_user.add_change(attr,"") # Special AD control attributes for attr, value in cereconf.AD_ACCOUNT_CONTROL.iteritems(): if attr in cb_user.ad_attrs: value = cb_user.ad_attrs[attr] if attr not in ad_user or ad_user[attr] != value: cb_user.add_change(attr, value) # Commit changes if cb_user.changes: self.commit_changes(dn, **cb_user.changes)
def compare_forwards(self, ad_contacts): """ Compare forward objects from AD with forward info in Cerebrum. @param ad_contacts: a dict of dicts wich maps contact obects name to that objects properties (dict) @type ad_contacts: dict """ for acc in self.accounts.itervalues(): for contact in acc.contact_objects: cb_fwd = contact.forward_attrs ad_fwd = ad_contacts.pop(cb_fwd['sAMAccountName'], None) if not ad_fwd: # Create AD contact object self.create_ad_contact(cb_fwd, self.default_ou) continue # contact object is in AD and Cerebrum -> compare OU # TBD: should OU's be compared? ou = cereconf.AD_CONTACT_OU cb_dn = 'CN=%s,%s' % (cb_fwd['sAMAccountName'], ou) if ad_fwd['distinguishedName'] != cb_dn: self.move_contact(cb_dn, ou) # Compare other attributes for attr_type, cb_fwd_attr in fwd.iteritems(): ad_fwd_attr = ad_fwd.get(attr_type) if cb_fwd_attr and ad_fwd_attr: # value both in ad and cerebrum => compare result = self.attr_cmp(cb_fwd_attr, ad_fwd_attr) if result: self.logger.debug("Changing attr %s from %s to %s", attr, unicode2str(ad_fwd_attr), unicode2str(cb_fwd_attr)) cb_user.add_change(attr, result) elif cb_fwd_attr: # attribute is not in AD and cerebrum value is set => update AD cb_user.add_change(attr, cb_fwd_attr) elif ad_fwd_attr: # value only in ad => delete value in ad # TBD: is this correct behavior? cb_user.add_change(attr,"") # Remaining contacts in AD should be deleted for ad_fwd in ad_contacts.itervalues(): self.delete_contact()