Search in sources :

Example 6 with BasicControl

use of javax.naming.ldap.BasicControl in project ldapsdk by pingidentity.

the class JNDIConverterTestCase method testToSDKControlWithMalformedValue.

/**
 * Provides test coverage for the method used to convert a non-{@code null}
 * JNDI control to an SDK control for a control which has a malformed value.
 *
 * @throws  Exception  If an unexpected problem occurs.
 */
@Test(expectedExceptions = { NamingException.class })
public void testToSDKControlWithMalformedValue() throws Exception {
    BasicControl jndiControl = new BasicControl("1.2.3.4", true, new byte[] { (byte) 0x01 });
    JNDIConverter.convertControl(jndiControl);
}
Also used : BasicControl(javax.naming.ldap.BasicControl) Test(org.testng.annotations.Test)

Example 7 with BasicControl

use of javax.naming.ldap.BasicControl in project openicf by Evolveum.

the class ActiveDirectoryChangeLogSyncStrategy method sync.

public void sync(SyncToken token, final SyncResultsHandler handler, final OperationOptions options) {
    if (oclass.is(DIRSYNC_EVENTS_OBJCLASS)) {
        handleEvents(token, handler, options);
    } else {
        // ldapsearch -h host -p 389 -b "ou=test,dc=example,dc=com" -D "cn=administrator,cn=users,dc=example,dc=com" -w xxx "(uSNChanged>=52410)"
        // We use the uSNchanged attribute to detect changes on entries and newly created entries.
        // We have to detect deleted entries as well. To do so, we use the filter (isDeleted==TRUE) to detect
        // the tombstones in the cn=delete objects,<defaultNamingContext> container.
        final TreeMap<Integer, SyncDelta> changes = new TreeMap<Integer, SyncDelta>();
        final String[] usnChanged = { "" };
        String waterMark = gethighestCommittedUSN();
        SearchControls controls = LdapInternalSearch.createDefaultSearchControls();
        controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
        controls.setDerefLinkFlag(false);
        LdapInternalSearch search = new LdapInternalSearch(conn, generateUSNChangedFilter(oclass, token, false), Arrays.asList(conn.getConfiguration().getBaseContextsToSynchronize()), new SimplePagedSearchStrategy(conn.getConfiguration().getBlockSize()), controls);
        try {
            search.execute(new LdapSearchResultsHandler() {

                public boolean handle(String baseDN, SearchResult result) throws NamingException {
                    Attributes attrs = result.getAttributes();
                    Uid uid = conn.getSchemaMapping().createUid(conn.getConfiguration().getUidAttribute(), attrs);
                    // build the object first
                    ConnectorObjectBuilder cob = new ConnectorObjectBuilder();
                    cob.setUid(uid);
                    if (ObjectClass.ALL.equals(oclass)) {
                        cob.setObjectClass(guessObjectClass(conn, attrs.get(OBJECTCLASS_ATTR)));
                    } else {
                        cob.setObjectClass(oclass);
                    }
                    cob.setName(result.getNameInNamespace());
                    if (attrs.get(LdapConstants.MS_GUID_ATTR) != null) {
                        cob.addAttribute(AttributeBuilder.build(LdapConstants.MS_GUID_ATTR, objectGUIDtoString(attrs.get(LdapConstants.MS_GUID_ATTR))));
                        attrs.remove(LdapConstants.MS_GUID_ATTR);
                    }
                    // Make sure we remove the SID
                    attrs.remove(OBJSID_ATTR);
                    // Make sure we're not hitting AD large group issue
                    if (ObjectClass.GROUP.equals(oclass)) {
                        // see: http://msdn.microsoft.com/en-us/library/ms817827.aspx
                        if (attrs.get("member;range=0-1499") != null) {
                            // we're in the limitation
                            Attribute range = AttributeBuilder.build("member", fetchGroupMembersByRange(conn, result));
                            cob.addAttribute(range);
                            if (conn.getConfiguration().isGetGroupMemberId()) {
                                cob.addAttribute(buildMemberIdAttribute(conn, range));
                            }
                            attrs.remove("member;range=0-1499");
                            attrs.remove("member");
                        }
                    }
                    // Process Account specifics (ENABLE/PASSWORD_EXPIRED/LOCKOUT/accountExpires/pwdLastSet)
                    if (oclass.equals(ObjectClass.ACCOUNT)) {
                        switch(conn.getServerType()) {
                            case MSAD_GC:
                            case MSAD:
                                if (attrs.get(ADUserAccountControl.MS_USR_ACCT_CTRL_ATTR) != null) {
                                    String controls = attrs.get(ADUserAccountControl.MS_USR_ACCT_CTRL_ATTR).get(0).toString();
                                    cob.addAttribute(AttributeBuilder.buildEnabled(!ADUserAccountControl.isAccountDisabled(controls)));
                                    cob.addAttribute(AttributeBuilder.buildLockOut(ADUserAccountControl.isAccountLockOut(controls)));
                                    cob.addAttribute(AttributeBuilder.buildPasswordExpired(ADUserAccountControl.isPasswordExpired(controls)));
                                }
                                break;
                            case MSAD_LDS:
                                if (attrs.get(LdapConstants.MS_DS_USER_ACCOUNT_DISABLED) != null) {
                                    cob.addAttribute(AttributeBuilder.buildEnabled(!Boolean.parseBoolean(attrs.get(LdapConstants.MS_DS_USER_ACCOUNT_DISABLED).get().toString())));
                                } else if (attrs.get(LdapConstants.MS_DS_USER_PASSWORD_EXPIRED) != null) {
                                    cob.addAttribute(AttributeBuilder.buildPasswordExpired(Boolean.parseBoolean(attrs.get(LdapConstants.MS_DS_USER_PASSWORD_EXPIRED).get().toString())));
                                } else if (attrs.get(LdapConstants.MS_DS_USER_ACCOUNT_AUTOLOCKED) != null) {
                                    cob.addAttribute(AttributeBuilder.buildLockOut(Boolean.parseBoolean(attrs.get(LdapConstants.MS_DS_USER_ACCOUNT_AUTOLOCKED).get().toString())));
                                }
                                break;
                            default:
                        }
                        if (attrs.get(ADLdapUtil.ACCOUNT_EXPIRES) != null) {
                            String value = (String) attrs.get(ADLdapUtil.ACCOUNT_EXPIRES).get();
                            if ("0".equalsIgnoreCase(value) || ADLdapUtil.ACCOUNT_NEVER_EXPIRES.equalsIgnoreCase(value)) {
                                // Let's set it to zero - this is equivalent: it means Never
                                cob.addAttribute(AttributeBuilder.build(ADLdapUtil.ACCOUNT_EXPIRES, "0"));
                            } else {
                                Date date = getJavaDateFromADTime(value);
                                cob.addAttribute(AttributeBuilder.build(ADLdapUtil.ACCOUNT_EXPIRES, getADLdapDatefromJavaDate(date)));
                            }
                            attrs.remove(ADLdapUtil.ACCOUNT_EXPIRES);
                        }
                        if (attrs.get(ADLdapUtil.PWD_LAST_SET) != null) {
                            String value = (String) attrs.get(ADLdapUtil.PWD_LAST_SET).get();
                            if ("0".equalsIgnoreCase(value)) {
                                cob.addAttribute(AttributeBuilder.build(ADLdapUtil.PWD_LAST_SET, "0"));
                            } else {
                                Date date = getJavaDateFromADTime(value);
                                cob.addAttribute(AttributeBuilder.build(ADLdapUtil.PWD_LAST_SET, getADLdapDatefromJavaDate(date)));
                            }
                            attrs.remove(ADLdapUtil.PWD_LAST_SET);
                        }
                    }
                    // Set all Attributes
                    NamingEnumeration<? extends javax.naming.directory.Attribute> attrsEnum = attrs.getAll();
                    while (attrsEnum.hasMore()) {
                        javax.naming.directory.Attribute attr = attrsEnum.next();
                        String id = attr.getID();
                        NamingEnumeration vals = attr.getAll();
                        ArrayList values = new ArrayList();
                        while (vals.hasMore()) {
                            values.add(vals.next());
                        }
                        cob.addAttribute(AttributeBuilder.build(id, values));
                        if (conn.getConfiguration().isGetGroupMemberId() && oclass.equals(ObjectClass.GROUP) && attr.getID().equalsIgnoreCase("member")) {
                            cob.addAttribute(buildMemberIdAttribute(conn, attr));
                        }
                    }
                    SyncDeltaBuilder syncDeltaBuilder = new SyncDeltaBuilder();
                    usnChanged[0] = attrs.get(USN_CHANGED_ATTR).get().toString();
                    if (usnChanged[0].equalsIgnoreCase(attrs.get(USN_CREATED_ATTR).get().toString())) {
                        syncDeltaBuilder.setDeltaType(SyncDeltaType.CREATE);
                    } else {
                        syncDeltaBuilder.setDeltaType(SyncDeltaType.UPDATE);
                    }
                    syncDeltaBuilder.setToken(new SyncToken(usnChanged[0]));
                    syncDeltaBuilder.setUid(uid);
                    syncDeltaBuilder.setObject(cob.build());
                    changes.put(Integer.parseInt(usnChanged[0]), syncDeltaBuilder.build());
                    return true;
                }
            });
        } catch (ConnectorException e) {
            if (e.getCause() instanceof PartialResultException) {
                // The default naming context is used on the DC as the baseContextsToSynchronize, hence this PartialResultException.
                // Let's just silently catch it not to break the sync cycle. It is thrown at the end of the search anyway...
                logger.warn("Default naming context of the DC is used as baseContextsToSynchronize.\nPartialResultException has been caught");
            } else {
                throw e;
            }
        }
        // ldapsearch -J 1.2.840.113556.1.4.417 -h xx -p 389 -b "dc=example,dc=com" -D "cn=administrator,cn=users,dc=example,dc=com" -w xx "&(isDeleted=TRUE)(uSNChanged>=528433)"
        if (conn.supportsControl(DELETE_CTRL)) {
            try {
                Attributes rootAttrs = conn.getInitialContext().getAttributes("", new String[] { NAMING_CTX_ATTR });
                String defaultContext = getStringAttrValue(rootAttrs, NAMING_CTX_ATTR);
                if (defaultContext != null) {
                    LdapContext context = conn.getInitialContext().newInstance(new Control[] { new BasicControl(DELETE_CTRL) });
                    NamingEnumeration<SearchResult> deleted = context.search(DELETED_PREFIX + defaultContext, generateUSNChangedFilter(oclass, token, true), controls);
                    while (deleted.hasMore()) {
                        SearchResult entry = deleted.next();
                        Attributes attrs = entry.getAttributes();
                        Uid uid = conn.getSchemaMapping().createUid(conn.getConfiguration().getUidAttribute(), attrs);
                        usnChanged[0] = attrs.get(USN_CHANGED_ATTR).get().toString();
                        SyncDeltaBuilder syncDeltaBuilder = new SyncDeltaBuilder();
                        syncDeltaBuilder.setToken(new SyncToken(usnChanged[0]));
                        syncDeltaBuilder.setDeltaType(SyncDeltaType.DELETE);
                        syncDeltaBuilder.setUid(uid);
                        if (ObjectClass.ALL.equals(oclass)) {
                            syncDeltaBuilder.setObjectClass(guessObjectClass(conn, attrs.get(OBJECTCLASS_ATTR)));
                        } else {
                            syncDeltaBuilder.setObjectClass(oclass);
                        }
                        changes.put(Integer.parseInt(usnChanged[0]), syncDeltaBuilder.build());
                    }
                } else if (LdapConnection.ServerType.MSAD_LDS.equals(conn.getServerType())) {
                    logger.error("Active Directory Lightweight Directory Services is used but defaultNamingContext has not been set - impossible to detect deleted objects");
                }
            } catch (NamingException e) {
                logger.info(e.getExplanation());
            }
        } else {
            logger.info("The server does not support the control to search for deleted entries");
        }
        // Changes are now ordered in the TreeMap according to usnChanged.
        for (Map.Entry<Integer, SyncDelta> entry : changes.entrySet()) {
            if (!handler.handle(entry.getValue())) {
                break;
            } else {
                waterMark = entry.getKey().toString();
            }
        }
        // ICF 1.4 now allows us to send the Token even if no entries were actually processed
        ((SyncTokenResultsHandler) handler).handleResult(new SyncToken(waterMark));
    }
}
Also used : Attribute(org.identityconnectors.framework.common.objects.Attribute) LdapUtil.buildMemberIdAttribute(org.identityconnectors.ldap.LdapUtil.buildMemberIdAttribute) ConnectorObjectBuilder(org.identityconnectors.framework.common.objects.ConnectorObjectBuilder) Attributes(javax.naming.directory.Attributes) ArrayList(java.util.ArrayList) NamingEnumeration(javax.naming.NamingEnumeration) PartialResultException(javax.naming.PartialResultException) ADLdapUtil.objectGUIDtoString(org.identityconnectors.ldap.ADLdapUtil.objectGUIDtoString) LdapInternalSearch(org.identityconnectors.ldap.search.LdapInternalSearch) SimplePagedSearchStrategy(org.identityconnectors.ldap.search.SimplePagedSearchStrategy) SyncDelta(org.identityconnectors.framework.common.objects.SyncDelta) SearchControls(javax.naming.directory.SearchControls) NamingException(javax.naming.NamingException) SyncTokenResultsHandler(org.identityconnectors.framework.spi.SyncTokenResultsHandler) LdapContext(javax.naming.ldap.LdapContext) BasicControl(javax.naming.ldap.BasicControl) SearchResult(javax.naming.directory.SearchResult) TreeMap(java.util.TreeMap) LdapSearchResultsHandler(org.identityconnectors.ldap.search.LdapSearchResultsHandler) Date(java.util.Date) ADLdapUtil.getADLdapDatefromJavaDate(org.identityconnectors.ldap.ADLdapUtil.getADLdapDatefromJavaDate) Uid(org.identityconnectors.framework.common.objects.Uid) SyncDeltaBuilder(org.identityconnectors.framework.common.objects.SyncDeltaBuilder) SyncToken(org.identityconnectors.framework.common.objects.SyncToken) ConnectorException(org.identityconnectors.framework.common.exceptions.ConnectorException) Map(java.util.Map) TreeMap(java.util.TreeMap)

Aggregations

BasicControl (javax.naming.ldap.BasicControl)7 Test (org.testng.annotations.Test)4 Control (com.unboundid.ldap.sdk.Control)3 ASN1OctetString (com.unboundid.asn1.ASN1OctetString)2 ArrayList (java.util.ArrayList)1 Date (java.util.Date)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 NamingEnumeration (javax.naming.NamingEnumeration)1 NamingException (javax.naming.NamingException)1 PartialResultException (javax.naming.PartialResultException)1 Attributes (javax.naming.directory.Attributes)1 SearchControls (javax.naming.directory.SearchControls)1 SearchResult (javax.naming.directory.SearchResult)1 LdapContext (javax.naming.ldap.LdapContext)1 Asn1Buffer (org.apache.directory.api.asn1.util.Asn1Buffer)1 OpaqueControl (org.apache.directory.api.ldap.model.message.controls.OpaqueControl)1 ConnectorException (org.identityconnectors.framework.common.exceptions.ConnectorException)1 Attribute (org.identityconnectors.framework.common.objects.Attribute)1 ConnectorObjectBuilder (org.identityconnectors.framework.common.objects.ConnectorObjectBuilder)1