def run(self, contactname, credopts=None, sambaopts=None, versionopts=None, H=None, surname=None, given_name=None, initials=None, force_new_cn=None, display_name=None, mail_address=None, reset_cn=None): # illegal options if force_new_cn and reset_cn: raise CommandError("It is not allowed to specify --force-new-cn " "together with --reset-cn.") if force_new_cn == "": raise CommandError("Failed to rename contact - delete protected " "attribute 'CN'") lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp, fallback_machine=True) samdb = SamDB(url=H, session_info=system_session(), credentials=creds, lp=lp) domain_dn = ldb.Dn(samdb, samdb.domain_dn()) filter = ("(&(objectClass=contact)(name=%s))" % ldb.binary_encode(contactname)) try: res = samdb.search(base=domain_dn, scope=ldb.SCOPE_SUBTREE, expression=filter, attrs=["name", "sn", "givenName", "cn", "initials", "displayName", "mail"] ) old_contact = res[0] contact_dn = old_contact.dn except IndexError: raise CommandError('Unable to find contact "%s"' % (contactname)) contact_parent_dn = contact_dn.parent() old_cn = old_contact["cn"][0] if force_new_cn is not None: new_cn = force_new_cn else: new_cn = samdb.fullname_from_names(old_attrs=old_contact, given_name=given_name, initials=initials, surname=surname) # change CN, if the new CN is different and the old CN is the # standard CN or the change is forced with force-new-cn or reset-cn excepted_cn = samdb.fullname_from_names(old_attrs=old_contact) must_change_cn = str(old_cn) != str(new_cn) and \ (str(old_cn) == str(excepted_cn) or \ reset_cn or bool(force_new_cn)) new_contact_dn = ldb.Dn(samdb, "CN=%s" % new_cn) new_contact_dn.add_base(contact_parent_dn) if new_cn == "" and must_change_cn: raise CommandError("Failed to rename contact '%s' - " "can not set an empty CN " "(please use --force-new-cn to specify a " "different CN or --given-name, --initials or " "--surname to set name attributes)" % old_cn) # format given attributes contact_attrs = ldb.Message() contact_attrs.dn = contact_dn samdb.prepare_attr_replace(contact_attrs, old_contact, "givenName", given_name) samdb.prepare_attr_replace(contact_attrs, old_contact, "sn", surname) samdb.prepare_attr_replace(contact_attrs, old_contact, "initials", initials) samdb.prepare_attr_replace(contact_attrs, old_contact, "displayName", display_name) samdb.prepare_attr_replace(contact_attrs, old_contact, "mail", mail_address) contact_attributes_changed = len(contact_attrs) > 0 # update the contact with formatted attributes samdb.transaction_start() try: if contact_attributes_changed == True: samdb.modify(contact_attrs) if must_change_cn: samdb.rename(contact_dn, new_contact_dn) except Exception as e: samdb.transaction_cancel() raise CommandError('Failed to rename contact "%s"' % contactname, e) samdb.transaction_commit() if must_change_cn: self.outf.write('Renamed CN of contact "%s" from "%s" to "%s" ' 'successfully\n' % (contactname, old_cn, new_cn)) if contact_attributes_changed: self.outf.write('Following attributes of contact "%s" have been ' 'changed successfully:\n' % (contactname)) for attr in contact_attrs.keys(): if attr == "dn": continue self.outf.write('%s: %s\n' % (attr, contact_attrs[attr] if contact_attrs[attr] else '[removed]'))