use of org.forgerock.opendj.ldap.Connection in project OpenAM by OpenRock.
the class DJLDAPv3Repo method getRoleMemberships.
/**
* Return the role membership informations for this given user. This will execute a read on the user entry to
* retrieve the nsRoleDN attribute. The values of the attribute will be returned.
*
* @param dn The DN of the user identity.
* @return The DNs of the roles this user is member of.
* @throws IdRepoException If there was an error while retrieving the role membership information.
*/
private Set<String> getRoleMemberships(String dn) throws IdRepoException {
Set<String> results = new HashSet<String>();
Connection conn = null;
try {
conn = connectionFactory.getConnection();
SearchResultEntry entry = conn.searchSingleEntry(LDAPRequests.newSingleEntrySearchRequest(dn, roleDNAttr));
Attribute attr = entry.getAttribute(roleDNAttr);
if (attr != null) {
results.addAll(LDAPUtils.getAttributeValuesAsStringSet(attr));
}
} catch (LdapException ere) {
DEBUG.error("An error occurred while trying to retrieve role memberships for " + dn + " using " + roleDNAttr + " attribute", ere);
handleErrorResult(ere);
} finally {
IOUtils.closeIfNotNull(conn);
}
return results;
}
use of org.forgerock.opendj.ldap.Connection in project OpenAM by OpenRock.
the class DJLDAPv3Repo method search.
/**
* Performs a search in the directory based on the provided parameters.
* Using the pattern and avPairs parameters an example search filter would look something like:
* <code>(&(|(attr1=value1)(attr2=value2))(searchAttr=pattern)(objectclassfilter))</code>.
*
* @param token Not used.
* @param type The type of the identity.
* @param crestQuery Either a string, coming from something like the CREST endpoint _queryId or a fully
* fledged query filter, coming from a CREST endpoint's _queryFilter
* @param maxTime The time limit for this search (in seconds). When maxTime < 1, the default time limit will
* be used.
* @param maxResults The number of maximum results we should receive for this search. When maxResults < 1 the
* default sizelimit will be used.
* @param returnAttrs The attributes that should be returned from the "search hits".
* @param returnAllAttrs <code>true</code> if all user attribute should be returned.
* @param filterOp When avPairs is provided, this logical operation will be used between them. Use
* {@link IdRepo#AND_MOD} or {@link IdRepo#OR_MOD}.
* @param avPairs Attribute-value pairs based on the search should be performed.
* @param recursive Deprecated setting, not used.
* @return The search results based on the provided parameters.
* @throws IdRepoException Shouldn't be thrown as the returned RepoSearchResults will contain the error code.
*/
@Override
public RepoSearchResults search(SSOToken token, IdType type, CrestQuery crestQuery, int maxTime, int maxResults, Set<String> returnAttrs, boolean returnAllAttrs, int filterOp, Map<String, Set<String>> avPairs, boolean recursive) throws IdRepoException {
if (DEBUG.messageEnabled()) {
DEBUG.message("search invoked with type: " + type + " crestQuery: " + crestQuery + " avPairs: " + avPairs + " maxTime: " + maxTime + " maxResults: " + maxResults + " returnAttrs: " + returnAttrs + " returnAllAttrs: " + returnAllAttrs + " filterOp: " + filterOp + " recursive: " + recursive);
}
DN baseDN = getBaseDN(type);
// Recursive is a deprecated setting on IdSearchControl, hence we should use the searchscope defined in the
// datastore configuration.
SearchScope scope = defaultScope;
String searchAttr = getSearchAttribute(type);
String[] attrs;
Filter first;
if (crestQuery.hasQueryId()) {
first = Filter.valueOf(searchAttr + "=" + crestQuery.getQueryId());
} else {
first = crestQuery.getQueryFilter().accept(new LdapFromJsonQueryFilterVisitor(), null);
}
Filter filter = Filter.and(first, getObjectClassFilter(type));
Filter tempFilter = constructFilter(filterOp, avPairs);
if (tempFilter != null) {
filter = Filter.and(tempFilter, filter);
}
if (returnAllAttrs || (returnAttrs != null && returnAttrs.contains("*"))) {
Set<String> predefinedAttrs = getDefinedAttributes(type);
attrs = predefinedAttrs.toArray(new String[predefinedAttrs.size()]);
returnAllAttrs = true;
} else if (returnAttrs != null && !returnAttrs.isEmpty()) {
returnAttrs.add(searchAttr);
attrs = returnAttrs.toArray(new String[returnAttrs.size()]);
} else {
attrs = new String[] { searchAttr };
}
SearchRequest searchRequest = LDAPRequests.newSearchRequest(baseDN, scope, filter, attrs);
searchRequest.setSizeLimit(maxResults < 1 ? defaultSizeLimit : maxResults);
searchRequest.setTimeLimit(maxTime < 1 ? defaultTimeLimit : maxTime);
Connection conn = null;
Set<String> names = new HashSet<String>();
Map<String, Map<String, Set<String>>> entries = new HashMap<String, Map<String, Set<String>>>();
int errorCode = RepoSearchResults.SUCCESS;
try {
conn = connectionFactory.getConnection();
ConnectionEntryReader reader = conn.search(searchRequest);
while (reader.hasNext()) {
Map<String, Set<String>> attributes = new HashMap<String, Set<String>>();
if (reader.isEntry()) {
SearchResultEntry entry = reader.readEntry();
String name = entry.parseAttribute(searchAttr).asString();
names.add(name);
if (returnAllAttrs) {
for (Attribute attribute : entry.getAllAttributes()) {
LDAPUtils.addAttributeToMapAsString(attribute, attributes);
}
entries.put(name, attributes);
} else if (returnAttrs != null && !returnAttrs.isEmpty()) {
for (String attr : returnAttrs) {
Attribute attribute = entry.getAttribute(attr);
if (attribute != null) {
LDAPUtils.addAttributeToMapAsString(attribute, attributes);
}
}
entries.put(name, attributes);
} else {
//there is no attribute to return, don't populate the entries map
}
} else {
//ignore search result references
reader.readReference();
}
}
} catch (LdapException ere) {
ResultCode resultCode = ere.getResult().getResultCode();
if (resultCode.equals(ResultCode.NO_SUCH_OBJECT)) {
return new RepoSearchResults(new HashSet<String>(0), RepoSearchResults.SUCCESS, Collections.EMPTY_MAP, type);
} else if (resultCode.equals(ResultCode.TIME_LIMIT_EXCEEDED) || resultCode.equals(ResultCode.CLIENT_SIDE_TIMEOUT)) {
errorCode = RepoSearchResults.TIME_LIMIT_EXCEEDED;
} else if (resultCode.equals(ResultCode.SIZE_LIMIT_EXCEEDED)) {
errorCode = RepoSearchResults.SIZE_LIMIT_EXCEEDED;
} else {
DEBUG.error("Unexpected error occurred during search", ere);
errorCode = resultCode.intValue();
}
} catch (SearchResultReferenceIOException srrioe) {
//should never ever happen...
DEBUG.error("Got reference instead of entry", srrioe);
throw newIdRepoException(IdRepoErrorCode.SEARCH_FAILED, CLASS_NAME);
} finally {
IOUtils.closeIfNotNull(conn);
}
return new RepoSearchResults(names, errorCode, entries, type);
}
use of org.forgerock.opendj.ldap.Connection in project OpenAM by OpenRock.
the class DJLDAPv3Repo method setAttributes.
/**
* Sets the provided attributes (string or binary) for the given identity. The following steps will be performed
* prior to modification:
* <ul>
* <li>The password will be encoded in case we are dealing with AD.</li>
* <li>Anything related to undefined attributes will be ignored.</li>
* <li>If the attribute map contains the default status attribute, then it will be converted to the status value
* specified in the configuration.</li>
* <li>In case changeOCs is set to <code>true</code>, the method will traverse through all the defined
* objectclasses to see if there is any attribute in the attributes map that is defined by that objectclass.
* These objectclasses will be collected and will be part of the modificationset with the other changes.</li>
* </ul>
* The attributes will be translated to modifications based on the followings:
* <ul>
* <li>If the attribute has no values in the map, it will be considered as an attribute DELETE.</li>
* <li>In any other case based on the value of isAdd parameter, it will be either ADD, or REPLACE.</li>
* </ul>
*
* @param token Not used.
* @param type The type of the identity.
* @param name The name of the identity.
* @param attributes The attributes that needs to be set for the entry.
* @param isAdd <code>true</code> if the attributes should be ADDed, <code>false</code> if the attributes should be
* REPLACEd instead.
* @param isString Whether the provided attributes are in string or binary format.
* @param changeOCs Whether the module should adjust the objectclasses for the entry or not.
* @throws IdRepoException Can be thrown in the following cases:
* <ul>
* <li>the identity cannot be found,</li>
* <li>there was a problem while retrieving the current user status from the directory (AD),</li>
* <li>there are no modifications to actually perform,</li>
* <li>there was an error while retrieving the objectClass attribute,</li>
* <li>there was an error while trying to read the directory schema,</li>
* <li>there was an error while trying to perform the modifications.</li>
* </ul>
*/
private void setAttributes(SSOToken token, IdType type, String name, Map attributes, boolean isAdd, boolean isString, boolean changeOCs) throws IdRepoException {
ModifyRequest modifyRequest = LDAPRequests.newModifyRequest(getDN(type, name));
attributes = removeUndefinedAttributes(type, attributes);
if (type.equals(IdType.USER)) {
Object status = attributes.get(DEFAULT_USER_STATUS_ATTR);
if (status != null && !attributes.containsKey(userStatusAttr)) {
String value = null;
if (status instanceof Set) {
value = ((Set<String>) status).iterator().next();
} else if (status instanceof byte[][]) {
value = new String(((byte[][]) status)[0], Charset.forName("UTF-8"));
}
value = helper.getStatus(this, name, !STATUS_INACTIVE.equals(value), userStatusAttr, activeValue, inactiveValue);
attributes.remove(DEFAULT_USER_STATUS_ATTR);
if (isString) {
attributes.put(userStatusAttr, asSet(value));
} else {
byte[][] binValue = new byte[1][];
binValue[0] = value.getBytes(Charset.forName("UTF-8"));
attributes.put(userStatusAttr, binValue);
}
}
}
for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) attributes.entrySet()) {
Object values = entry.getValue();
String attrName = entry.getKey();
Attribute attr = new LinkedAttribute(attrName);
if (AD_UNICODE_PWD_ATTR.equalsIgnoreCase(attrName)) {
if (values instanceof byte[][]) {
attr.add(ByteString.valueOfBytes(helper.encodePassword(IdType.USER, (byte[][]) values)));
} else {
attr.add(ByteString.valueOfBytes(helper.encodePassword(IdType.USER, (Set) values)));
}
} else if (values instanceof byte[][]) {
for (byte[] bytes : (byte[][]) values) {
attr.add(ByteString.valueOfBytes(bytes));
}
} else if (values instanceof Set) {
for (String value : (Set<String>) values) {
attr.add(value);
}
}
if (attr.isEmpty()) {
modifyRequest.addModification(new Modification(ModificationType.REPLACE, attr));
} else {
modifyRequest.addModification(new Modification(isAdd ? ModificationType.ADD : ModificationType.REPLACE, attr));
}
}
if (modifyRequest.getModifications().isEmpty()) {
if (DEBUG.messageEnabled()) {
DEBUG.message("setAttributes: there are no modifications to perform");
}
throw newIdRepoException(IdRepoErrorCode.ILLEGAL_ARGUMENTS);
}
if (type.equals(IdType.USER) && changeOCs) {
Set<String> missingOCs = new CaseInsensitiveHashSet();
Map<String, Set<String>> attrs = getAttributes(token, type, name, asSet(OBJECT_CLASS_ATTR));
Set<String> ocs = attrs.get(OBJECT_CLASS_ATTR);
//to missingOCs
if (ocs != null) {
missingOCs.addAll(getObjectClasses(type));
missingOCs.removeAll(ocs);
}
//if the missingOCs is not empty (i.e. there are objectclasses that are not present in the entry yet)
if (!missingOCs.isEmpty()) {
Object obj = attributes.get(OBJECT_CLASS_ATTR);
//if the API user has also added some of his objectclasses, then let's remove those from missingOCs
if (obj != null && obj instanceof Set) {
missingOCs.removeAll((Set<String>) obj);
}
//for every single objectclass that needs to be added, let's check if they contain an attribute that we
//wanted to add to the entry.
Set<String> newOCs = new HashSet<String>(2);
Schema dirSchema = getSchema();
for (String objectClass : missingOCs) {
try {
ObjectClass oc = dirSchema.getObjectClass(objectClass);
//we should never add new structural objectclasses, see RFC 4512
if (!oc.getObjectClassType().equals(ObjectClassType.STRUCTURAL)) {
for (String attrName : (Set<String>) attributes.keySet()) {
//before we start to add too many objectclasses here...
if (!attrName.equalsIgnoreCase(OBJECT_CLASS_ATTR) && oc.isRequiredOrOptional(dirSchema.getAttributeType(attrName))) {
newOCs.add(objectClass);
break;
}
}
}
} catch (UnknownSchemaElementException usee) {
if (DEBUG.warningEnabled()) {
DEBUG.warning("Unable to find a schema element: " + usee.getMessage());
}
}
}
missingOCs = newOCs;
//it is possible that none of the missing objectclasses are actually covering any new attributes
if (!missingOCs.isEmpty()) {
//based on these let's add the extra objectclasses to the modificationset
modifyRequest.addModification(new Modification(ModificationType.ADD, new LinkedAttribute(OBJECT_CLASS_ATTR, missingOCs)));
}
}
}
Connection conn = null;
try {
conn = connectionFactory.getConnection();
conn.modify(modifyRequest);
} catch (LdapException ere) {
DEBUG.error("An error occured while setting attributes for identity: " + name, ere);
handleErrorResult(ere);
} finally {
IOUtils.closeIfNotNull(conn);
}
}
use of org.forgerock.opendj.ldap.Connection in project OpenAM by OpenRock.
the class DJLDAPv3Repo method getGroupMemberships.
/**
* Returns the group membership informations for this given user. In case the memberOf attribute is configured,
* this will try to query the user entry and return the group DNs found in the memberOf attribute. Otherwise a
* search request will be issued using the uniqueMember attribute looking for matches with the user DN.
*
* @param dn The DN of the user identity.
* @return The DNs of the groups that the provided user is member of.
* @throws IdRepoException If there was an error while retrieving the group membership information.
*/
private Set<String> getGroupMemberships(String dn) throws IdRepoException {
Set<String> results = new HashSet<String>();
if (memberOfAttr == null) {
Filter filter = Filter.and(groupSearchFilter, Filter.equality(uniqueMemberAttr, dn));
SearchRequest searchRequest = LDAPRequests.newSearchRequest(getBaseDN(IdType.GROUP), defaultScope, filter, DN_ATTR);
searchRequest.setTimeLimit(defaultTimeLimit);
searchRequest.setSizeLimit(defaultSizeLimit);
Connection conn = null;
try {
conn = connectionFactory.getConnection();
ConnectionEntryReader reader = conn.search(searchRequest);
while (reader.hasNext()) {
if (reader.isEntry()) {
results.add(reader.readEntry().getName().toString());
} else {
//ignore search result references
reader.readReference();
}
}
} catch (LdapException ere) {
DEBUG.error("An error occurred while trying to retrieve group memberships for " + dn + " using " + uniqueMemberAttr, ere);
handleErrorResult(ere);
} catch (SearchResultReferenceIOException srrioe) {
//should never ever happen...
DEBUG.error("Got reference instead of entry", srrioe);
throw newIdRepoException(IdRepoErrorCode.SEARCH_FAILED, CLASS_NAME);
} finally {
IOUtils.closeIfNotNull(conn);
}
} else {
Connection conn = null;
try {
conn = connectionFactory.getConnection();
SearchResultEntry entry = conn.searchSingleEntry(LDAPRequests.newSingleEntrySearchRequest(dn, memberOfAttr));
Attribute attr = entry.getAttribute(memberOfAttr);
if (attr != null) {
results.addAll(LDAPUtils.getAttributeValuesAsStringSet(attr));
}
} catch (LdapException ere) {
DEBUG.error("An error occurred while trying to retrieve group memberships for " + dn + " using " + memberOfAttr + " attribute", ere);
handleErrorResult(ere);
} finally {
IOUtils.closeIfNotNull(conn);
}
}
return results;
}
use of org.forgerock.opendj.ldap.Connection in project OpenAM by OpenRock.
the class AMCRLStore method getCRL.
/**
* Checks certificate and returns corresponding stored CRL in ldap store
*
* @param certificate
*/
public X509CRL getCRL(X509Certificate certificate) throws IOException {
SearchResultEntry crlEntry = null;
X509CRL crl = null;
if (storeParam.isDoCRLCaching()) {
if (debug.messageEnabled()) {
debug.message("AMCRLStore.getCRL: Trying to get CRL from cache");
}
crl = getCRLFromCache(certificate);
}
try (Connection ldc = getConnection()) {
if (ldc == null) {
return null;
}
if (crl == null) {
if (debug.messageEnabled()) {
debug.message("AMCRLStore.getCRL: crl is null");
}
if (mCrlAttrName == null) {
crlEntry = getLdapEntry(ldc, CERTIFICATE_REVOCATION_LIST, CERTIFICATE_REVOCATION_LIST_BINARY);
} else {
crlEntry = getLdapEntry(ldc, mCrlAttrName);
}
crl = getCRLFromEntry(crlEntry);
}
if (storeParam.isDoUpdateCRLs() && needCRLUpdate(crl)) {
if (debug.messageEnabled()) {
debug.message("AMCRLStore.getCRL: need CRL update");
}
X509CRL tmpcrl = null;
IssuingDistributionPointExtension crlIDPExt = null;
try {
if (crl != null) {
crlIDPExt = getCRLIDPExt(crl);
}
} catch (Exception e) {
debug.message("AMCRLStore.getCRL: crlIDPExt is null");
}
CRLDistributionPointsExtension crlDPExt = null;
try {
crlDPExt = getCRLDPExt(certificate);
} catch (Exception e) {
debug.message("AMCRLStore.getCRL: crlDPExt is null");
}
if ((tmpcrl == null) && (crlIDPExt != null)) {
tmpcrl = getUpdateCRLFromCrlIDP(crlIDPExt);
}
if ((tmpcrl == null) && (crlDPExt != null)) {
tmpcrl = getUpdateCRLFromCrlDP(crlDPExt);
}
if (tmpcrl != null) {
if (crlEntry == null) {
crlEntry = getLdapEntry(ldc);
}
if (debug.messageEnabled()) {
debug.message("AMCRLStore.getCRL: new crl = " + tmpcrl);
}
if (crlEntry != null) {
updateCRL(ldc, crlEntry.getName().toString(), tmpcrl.getEncoded());
}
}
crl = tmpcrl;
}
if (storeParam.isDoCRLCaching()) {
if (debug.messageEnabled()) {
debug.message("AMCRLStore.getCRL: Updating CRL cache");
}
updateCRLCache(certificate, crl);
}
} catch (Exception e) {
debug.error("AMCRLStore.getCRL: Error in getting CRL : ", e);
}
return crl;
}
Aggregations