org.connid.bundles.ad.crud.ADUpdate Maven / Gradle / Ivy
The newest version!
/**
* Copyright (C) 2011 ConnId ([email protected])
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.connid.bundles.ad.crud;
import static org.connid.bundles.ad.ADConnector.*;
import static org.connid.bundles.ldap.commons.LdapUtil.checkedListByFilter;
import static org.identityconnectors.common.CollectionUtil.isEmpty;
import static org.identityconnectors.common.CollectionUtil.newSet;
import static org.identityconnectors.common.CollectionUtil.nullAsEmpty;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import javax.naming.InvalidNameException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import net.tirasa.adsddl.ntsd.SID;
import net.tirasa.adsddl.ntsd.utils.Hex;
import net.tirasa.adsddl.ntsd.utils.NumberFacility;
import org.connid.bundles.ad.ADConfiguration;
import org.connid.bundles.ad.ADConnection;
import org.connid.bundles.ad.util.ADGuardedPasswordAttribute;
import org.connid.bundles.ad.util.ADGuardedPasswordAttribute.Accessor;
import org.connid.bundles.ad.util.ADUtilities;
import org.connid.bundles.ldap.commons.GroupHelper.GroupMembership;
import org.connid.bundles.ldap.commons.GroupHelper.Modification;
import org.connid.bundles.ldap.commons.LdapConstants;
import org.connid.bundles.ldap.commons.LdapModifyOperation;
import org.identityconnectors.common.Pair;
import org.identityconnectors.common.StringUtil;
import org.identityconnectors.common.logging.Log;
import org.identityconnectors.framework.common.exceptions.ConnectorException;
import org.identityconnectors.framework.common.objects.Attribute;
import org.identityconnectors.framework.common.objects.AttributeBuilder;
import org.identityconnectors.framework.common.objects.AttributeUtil;
import org.identityconnectors.framework.common.objects.ConnectorObject;
import org.identityconnectors.framework.common.objects.Name;
import org.identityconnectors.framework.common.objects.ObjectClass;
import org.identityconnectors.framework.common.objects.OperationalAttributes;
import org.identityconnectors.framework.common.objects.Uid;
public class ADUpdate extends LdapModifyOperation {
private static final Log LOG = Log.getLog(ADUpdate.class);
private final ObjectClass oclass;
private final Uid uid;
private final ADUtilities utils;
@SuppressWarnings("FieldNameHidesFieldInSuperclass")
private final ADConnection conn;
/**
* Retrieve new name if specified.
*
* @return new Name if provider; null otherwise.
*/
private Name getNewName(final String entryDN, final Set attrs) {
// purge CN
final Attribute cnAttr = AttributeUtil.find(ADConfiguration.CN_NAME, attrs);
if (cnAttr != null) {
attrs.remove(cnAttr);
}
// retrieve new name...
final Name name = AttributeUtil.getNameFromAttributes(attrs);
Name newName = null;
if (name != null) {
attrs.remove(name);
if (utils.isDN(name.getNameValue())) {
newName = new Name(conn.getSchemaMapping().getEntryDN(oclass, name));
}
}
if (newName == null
&& !conn.getConfiguration().getUidAttribute().equalsIgnoreCase(ADConfiguration.CN_NAME)
&& cnAttr != null) {
final String cnValue = cnAttr.getValue() == null || cnAttr.getValue().isEmpty() || cnAttr.getValue().get(0)
== null
? null
: cnAttr.getValue().get(0).toString();
try {
// rename if and only if Name is a DN or CN has been provided (consider that the CN can be the Name)
final List rdns = new ArrayList(new LdapName(entryDN).getRdns());
Rdn naming = new Rdn(rdns.get(rdns.size() - 1).getType(), cnValue);
rdns.remove(rdns.size() - 1);
rdns.add(naming);
newName = new Name(new LdapName(rdns).toString());
} catch (InvalidNameException e) {
LOG.error("Error retrieving new DN. Ignore rename request.", e);
}
}
return newName;
}
public ADUpdate(final ADConnection conn, final ObjectClass oclass, final Uid uid) {
super(conn);
this.utils = new ADUtilities(conn);
this.oclass = oclass;
this.uid = uid;
this.conn = conn;
}
public Uid update(final Set attrs) {
final ConnectorObject obj = utils.getEntryToBeUpdated(uid, oclass);
String entryDN = obj.getName().getNameValue();
// ---------------------------------
// Check if entry should be renamed.
// ---------------------------------
final Set attrsToBeUpdated = newSet(attrs);
final Name newName = getNewName(entryDN, attrsToBeUpdated);
// ---------------------------------
// ---------------------------------
// Perform modify/rename
// ---------------------------------
final Pair attrToModify = getAttributesToModify(obj, attrsToBeUpdated);
// Update the attributes.
modifyAttributes(entryDN, attrToModify, DirContext.REPLACE_ATTRIBUTE);
// Rename the entry if needed.
if (newName != null) {
entryDN = conn.getSchemaMapping().rename(oclass, entryDN, newName);
}
// ---------------------------------
// ---------------------------------
// Perform group memberships
// ---------------------------------
final List ldapGroups = getStringListValue(attrsToBeUpdated, LdapConstants.LDAP_GROUPS_NAME);
if (ldapGroups != null) {
final Set oldMemberships = new TreeSet(String.CASE_INSENSITIVE_ORDER);
oldMemberships.addAll(groupHelper.getLdapGroups(entryDN));
String primaryGroup = null;
final ConnectorObject profile = utils.getEntryToBeUpdated(uid, oclass);
final Attribute primaryGroupID = profile.getAttributeByName(PRIMARYGROUPID);
if (primaryGroupID != null && primaryGroupID.getValue() != null && !primaryGroupID.getValue().isEmpty()) {
final byte[] pgID = NumberFacility.getUIntBytes(
Long.parseLong(primaryGroupID.getValue().get(0).toString()));
final SID pgSID = SID.parse((byte[]) profile.getAttributeByName(OBJECTSID).getValue().get(0));
pgSID.getSubAuthorities().remove(pgSID.getSubAuthorityCount() - 1);
pgSID.addSubAuthority(pgID);
final Set res = utils.basicLdapSearch(String.format(
"(&(objectclass=group)(%s=%s))", OBJECTSID, Hex.getEscaped(pgSID.toByteArray())));
if (res == null || res.isEmpty()) {
LOG.warn("Error retrieving primary group for {0}", entryDN);
} else {
primaryGroup = res.iterator().next().getNameInNamespace();
LOG.info("Found primary group {0}", primaryGroup);
}
}
final Set newMemberships = new TreeSet(String.CASE_INSENSITIVE_ORDER);
newMemberships.addAll(ldapGroups);
if (StringUtil.isNotBlank(primaryGroup)) {
newMemberships.remove(primaryGroup);
}
// Update the LDAP groups.
final Modification ldapGroupMod = new Modification();
if (!newMemberships.equals(oldMemberships)) {
final Set toBeRemoved = new TreeSet(String.CASE_INSENSITIVE_ORDER);
toBeRemoved.addAll(oldMemberships);
toBeRemoved.removeAll(newMemberships);
for (String membership : toBeRemoved) {
ldapGroupMod.remove(new GroupMembership(entryDN, membership));
}
final Set toBeAdded = new TreeSet(String.CASE_INSENSITIVE_ORDER);
toBeAdded.addAll(newMemberships);
toBeAdded.removeAll(oldMemberships);
for (String membership : toBeAdded) {
ldapGroupMod.add(new GroupMembership(entryDN, membership));
}
}
groupHelper.modifyLdapGroupMemberships(ldapGroupMod);
}
// ---------------------------------
return conn.getSchemaMapping().createUid(oclass, entryDN);
}
public Uid addAttributeValues(Set attrs) {
final ConnectorObject obj = utils.getEntryToBeUpdated(uid, oclass);
final String entryDN = obj.getName().getNameValue();
final Pair attrsToModify = getAttributesToModify(obj, attrs);
modifyAttributes(entryDN, attrsToModify, DirContext.ADD_ATTRIBUTE);
List ldapGroups = getStringListValue(attrs, LdapConstants.LDAP_GROUPS_NAME);
if (!isEmpty(ldapGroups)) {
groupHelper.addLdapGroupMemberships(entryDN, ldapGroups);
}
return uid;
}
public Uid removeAttributeValues(Set attrs) {
final ConnectorObject obj = utils.getEntryToBeUpdated(uid, oclass);
final String entryDN = obj.getName().getNameValue();
final Pair attrsToModify = getAttributesToModify(obj, attrs);
modifyAttributes(entryDN, attrsToModify, DirContext.REMOVE_ATTRIBUTE);
List ldapGroups = getStringListValue(attrs, LdapConstants.LDAP_GROUPS_NAME);
if (!isEmpty(ldapGroups)) {
groupHelper.removeLdapGroupMemberships(entryDN, ldapGroups);
}
return uid;
}
private Pair getAttributesToModify(
final ConnectorObject obj, final Set attrs) {
final BasicAttributes ldapAttrs = new BasicAttributes();
ADGuardedPasswordAttribute pwdAttr = null;
int uacValue = -1;
for (Attribute attr : attrs) {
javax.naming.directory.Attribute ldapAttr = null;
if (attr.is(Uid.NAME)) {
throw new IllegalArgumentException("Unable to modify an object's uid");
} else if (attr.is(Name.NAME)) {
// Such a change would have been handled in update() above.
throw new IllegalArgumentException("Unable to modify an object's name");
} else if (attr.is(ADConfiguration.UCCP_FLAG)) {
final List © 2015 - 2025 Weber Informatics LLC | Privacy Policy