下面列出了javax.naming.ldap.LdapContext#search ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
public List<Attributes> searchByFilter(String dn, String filter){
try {
LdapContext context = connectionService.getContext();
NamingEnumeration<SearchResult> searchResults = context.search(dn, filter, new SearchControls());
List<Attributes> attributesList = new ArrayList<>();
while (searchResults.hasMore()) {
SearchResult searchResult = searchResults.next();
attributesList.add(searchResult.getAttributes());
}
return attributesList;
} catch (NamingException ex) {
throw new CukesRuntimeException(ex);
} finally {
connectionService.close();
}
}
/**
* 获取对应账户的用户名 (通过account获取userName)
* 该方法在用户名密码验证失败后会抛出异常,根据异常判断用户名密码是否正确,用户是否存在
*
* @param account
* @param ctx
* @return
* @throws NamingException
*/
private String applyUserName(String account, LdapContext ctx) throws NamingException {
String userName = null;
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[]{"uid", "userPassword", "displayName", "cn", "sn", "mail", "description"});
String searchFilter = String.format(SEARCH_FILTER, account, account, account);
NamingEnumeration<SearchResult> answer = ctx.search("DC=purang,DC=com", searchFilter, searchControls);
while (answer.hasMoreElements()) {
SearchResult sr = answer.next();
String[] qResult = sr.getName().split(",");
if (qResult.length > 1) {
userName = qResult[0].split("=")[1];
}
}
return userName;
}
/**
* Simple version of {@link #listBy(LdapSearchOption, String, Object...)} but this one will not map the return
* attributes and let you do that and will not take an {@link LdapSearchOption} as template for search
*
* @param filter to be applied
* @param parameters to be applied to the filter
* @return a {@link List} of {@link Attributes} found
*/
public List<Attributes> listBy(String filter, Object... parameters) {
final SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
final List<Attributes> attributes = new ArrayList<>();
try {
final LdapContext context = this.factory.getSystemLdapContext();
final NamingEnumeration<SearchResult> answer = context.search(this.baseDN, filter, parameters, searchControls);
while (answer.hasMoreElements()) {
final SearchResult searchResult = answer.nextElement();
attributes.add(searchResult.getAttributes());
}
} catch (NamingException ex) {
throw new BusinessLogicException("error.ldap.cant-search-for-users", ex);
}
return attributes;
}
public void deleteEntityByDn(String dn) {
try {
LdapContext context = connectionService.getContext();
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> children = context.search(dn, "(objectclass=*)", searchControls);
TreeSet<String> dnsToDelete = new TreeSet<>(new DnComparator(true));
while (children.hasMoreElements()) {
SearchResult childResult = children.nextElement();
String childDn = childResult.getNameInNamespace();
dnsToDelete.add(childDn);
}
for (String s : dnsToDelete) {
context.destroySubcontext(s);
}
} catch (NamingException e) {
throw new CukesRuntimeException("Cannot delete entity by dn " + dn, e);
} finally {
connectionService.close();
}
}
private void doInitUser(Map<String, UserInfo> userInfos, Map<String, Organization> orgMap, String serverPath)
throws NamingException {
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
env.put(Context.SECURITY_AUTHENTICATION, "simple");
env.put(Context.SECURITY_PRINCIPAL, "corp\\" + soaConfig.getMqLdapUser());
env.put(Context.SECURITY_CREDENTIALS, soaConfig.getMqLdapPass());
env.put(Context.PROVIDER_URL, adServer.get());
LdapContext ctx = new InitialLdapContext(env, null);
SearchControls searchCtls = new SearchControls();
searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
String searchFilter = String
.format("(&(objectClass=top)(objectClass=user)(objectClass=person)(objectClass=organizationalPerson))");
String returnedAtts[] = { "memberOf", "sAMAccountName", "cn", "distinguishedName", "mail" };
searchCtls.setReturningAttributes(returnedAtts);
NamingEnumeration<SearchResult> answer = ctx.search(serverPath, searchFilter, searchCtls);
while (answer.hasMoreElements()) {
SearchResult sr = (SearchResult) answer.next();
Attributes at = sr.getAttributes();
UserInfo userInfo = new UserInfo();
userInfo.setDepartment(getDValue(at.get("distinguishedName")));
userInfo.setEmail(getValue(at.get("mail")));
userInfo.setUserId(getValue(at.get("sAMAccountName")));
userInfo.setName(getValue(at.get("cn")));
userInfo.setAdmin(roleService.isAdmin(userInfo.getUserId()));
userInfos.put(userInfo.getUserId(), userInfo);
if (!StringUtils.isEmpty(userInfo.getDepartment())) {
Organization organization = new Organization();
organization.setOrgId(userInfo.getDepartment());
orgMap.put(userInfo.getDepartment(), organization);
}
}
ctx.close();
}
/**
* Finds a distinguished name(DN) of a user by querying the active directory LDAP context for the
* specified username.
*
* @return the DN of the user, or {@code null} if there's no such user
*/
@Nullable
protected String findUserDn(LdapContextFactory ldapContextFactory, String username) throws NamingException {
LdapContext ctx = null;
try {
// Binds using the system username and password.
ctx = ldapContextFactory.getSystemLdapContext();
final SearchControls ctrl = new SearchControls();
ctrl.setCountLimit(1);
ctrl.setSearchScope(SearchControls.SUBTREE_SCOPE);
ctrl.setTimeLimit(searchTimeoutMillis);
final String filter =
searchFilter != null ? USERNAME_PLACEHOLDER.matcher(searchFilter)
.replaceAll(username)
: username;
final NamingEnumeration<SearchResult> result = ctx.search(searchBase, filter, ctrl);
try {
if (!result.hasMore()) {
return null;
}
return result.next().getNameInNamespace();
} finally {
result.close();
}
} finally {
LdapUtils.closeContext(ctx);
}
}
private boolean isPagedResultControlSupported(final LdapContext ctx) {
try {
final SearchControls ctl = new SearchControls();
ctl.setReturningAttributes(new String[] { "supportedControl" });
ctl.setSearchScope(SearchControls.OBJECT_SCOPE);
/* search for the rootDSE object */
final NamingEnumeration<SearchResult> results = ctx.search("", "(objectClass=*)", ctl);
while (results.hasMore()) {
final SearchResult entry = results.next();
final NamingEnumeration<? extends Attribute> attrs = entry.getAttributes().getAll();
while (attrs.hasMore()) {
final Attribute attr = attrs.next();
final NamingEnumeration<?> vals = attr.getAll();
while (vals.hasMore()) {
final String value = (String) vals.next();
if (value.equals(PAGED_RESULT_CONTROL_OID)) {
return true;
}
}
}
}
return false;
} catch (final Exception e) {
log.error("Exception when trying to know if the server support paged results.", e);
return false;
}
}
private LdapUser getUserForDn(final String userdn, final LdapContext context) throws NamingException {
final SearchControls controls = new SearchControls();
controls.setSearchScope(_ldapConfiguration.getScope());
controls.setReturningAttributes(_ldapConfiguration.getReturnAttributes());
final NamingEnumeration<SearchResult> result = context.search(userdn, "(objectClass=" + _ldapConfiguration.getUserObject() + ")", controls);
if (result.hasMoreElements()) {
return createUser(result.nextElement());
} else {
throw new NamingException("No user found for dn " + userdn);
}
}
@Override
protected AuthenticationInfo createAuthenticationInfo(AuthenticationToken token, Object ldapPrincipal, Object ldapCredentials, LdapContext ldapContext) throws NamingException {
SimpleAuthenticationInfo authenticationInfo = (SimpleAuthenticationInfo) super.createAuthenticationInfo(token, ldapPrincipal, ldapCredentials, ldapContext);
MutablePrincipalCollection mpc = (MutablePrincipalCollection) authenticationInfo.getPrincipals();
final SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
// get all attributes
constraints.setReturningAttributes(null);
String templ = getUserDnTemplate();
String userDn = MessageFormat.format(templ, mpc.getPrimaryPrincipal());
final NamingEnumeration<SearchResult> answer = ldapContext.search(userDn, "(objectClass=*)", constraints);
if (answer.hasMore()) {
Attributes attrs = answer.next().getAttributes();
if (answer.hasMore()) {
throw new NamingException("Non-unique user specified by:" + userDn);
}
//TODO: make this Guicy
User user = new UserFromLdap(attrs, mpc);
// at present there should only be one realm involved.
Iterator<String> realmIter = mpc.getRealmNames().iterator();
String firstRealm = realmIter.next();
if (realmIter.hasNext()) {
// ugh, need a new solution here
String explanation = String.format("More than one realm found! (%s and %s)", firstRealm, realmIter.next());
throw new NamingException(explanation);
}
mpc.add(user,firstRealm);
} else {
throw new NamingException("Invalid User specified by:" + userDn);
}
return authenticationInfo;
}
@Override
public List<LdapUser> getUsersInGroup(String groupName, LdapContext context, Long domainId) throws NamingException {
String attributeName = _ldapConfiguration.getGroupUniqueMemberAttribute(domainId);
final SearchControls controls = new SearchControls();
controls.setSearchScope(_ldapConfiguration.getScope());
controls.setReturningAttributes(new String[] {attributeName});
NamingEnumeration<SearchResult> result = context.search(_ldapConfiguration.getBaseDn(domainId), generateGroupSearchFilter(groupName, domainId), controls);
final List<LdapUser> users = new ArrayList<LdapUser>();
//Expecting only one result which has all the users
if (result.hasMoreElements()) {
Attribute attribute = result.nextElement().getAttributes().get(attributeName);
NamingEnumeration<?> values = attribute.getAll();
while (values.hasMoreElements()) {
String userdn = String.valueOf(values.nextElement());
try{
users.add(getUserForDn(userdn, context, domainId));
} catch (NamingException e){
LOGGER.info("Userdn: " + userdn + " Not Found:: Exception message: " + e.getMessage());
}
}
}
Collections.sort(users);
return users;
}
private boolean isPagedResultControlSupported(final LdapContext ctx) {
try {
final SearchControls ctl = new SearchControls();
ctl.setReturningAttributes(new String[] { "supportedControl" });
ctl.setSearchScope(SearchControls.OBJECT_SCOPE);
/* search for the rootDSE object */
final NamingEnumeration<SearchResult> results = ctx.search("", "(objectClass=*)", ctl);
while (results.hasMore()) {
final SearchResult entry = results.next();
final NamingEnumeration<? extends Attribute> attrs = entry.getAttributes().getAll();
while (attrs.hasMore()) {
final Attribute attr = attrs.next();
final NamingEnumeration<?> vals = attr.getAll();
while (vals.hasMore()) {
final String value = (String) vals.next();
if (value.equals(PAGED_RESULT_CONTROL_OID)) {
return true;
}
}
}
}
return false;
} catch (final Exception e) {
log.error("Exception when trying to know if the server support paged results.", e);
return false;
}
}
private void findAdvGroupProperties(LdapContext ldapContext) throws Throwable {
int noOfGroups = 0;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
SearchControls groupSearchControls = new SearchControls();
groupSearchControls.setSearchScope(config.getGroupSearchScope());
Set<String> groupSearchAttributes = new HashSet<>();
groupSearchAttributes.add(groupNameAttrName);
groupSearchAttributes.add(groupMemberName);
groupSearchAttributes.add("distinguishedName");
groupSearchControls.setReturningAttributes(groupSearchAttributes.toArray(
new String[groupSearchAttributes.size()]));
String extendedGroupSearchFilter = "(objectclass=" + groupObjClassName + ")";
try {
HashMap<String, Integer> ouOccurences = new HashMap<>();
if (groupSearchBase == null || groupSearchBase.isEmpty()) {
groupSearchResultEnum = ldapContext.search(searchBase, extendedGroupSearchFilter,
groupSearchControls);
} else {
groupSearchResultEnum = ldapContext.search(groupSearchBase, extendedGroupSearchFilter,
groupSearchControls);
}
while (groupSearchResultEnum.hasMore()) {
if (noOfGroups >= 20) {
break;
}
final SearchResult groupEntry = groupSearchResultEnum.next();
if (groupEntry == null) {
continue;
}
Attributes groupAttributes = groupEntry.getAttributes();
if (groupAttributes == null) {
logFile.println("WARN: Attributes missing for entry " + groupEntry.getNameInNamespace());
continue;
}
String dnValue;
Attribute dnAttr = groupAttributes.get("distinguishedName");
if (dnAttr != null) {
dnValue = dnAttr.get().toString();
String ouStr = "OU=";
int indexOfOU = dnValue.indexOf(ouStr);
if (indexOfOU > 0) {
dnValue = dnValue.substring(indexOfOU);
} else {
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
} else {
// If distinguishedName is not found,
// strip off the userName from the long name for OU or sub domain
dnValue = groupEntry.getNameInNamespace();
dnValue = dnValue.substring(dnValue.indexOf(",") + 1);
}
//System.out.println("OU from dn = " + dnValue);
Integer ouOccrs = ouOccurences.get(dnValue);
if (ouOccrs == null) {
//System.out.println("value = 0");
ouOccrs = Integer.valueOf(0);
}
int val = ouOccrs.intValue();
ouOccrs = Integer.valueOf(++val);
ouOccurences.put(dnValue, ouOccrs);
noOfGroups++;
}
if (!ouOccurences.isEmpty()) {
Set<String> keys = ouOccurences.keySet();
int maxOUOccr = 0;
for (String key : keys) {
int ouOccurVal = ouOccurences.get(key).intValue();
logFile.println("INFO: No. of groups from " + key + " = " + ouOccurVal);
if (ouOccurVal > maxOUOccr) {
maxOUOccr = ouOccurVal;
groupSearchBase = key;
}
}
}
if (groupSearchFilter == null || groupSearchFilter.isEmpty()) {
groupSearchFilter = groupNameAttrName + "=*";
}
installProps.println("SYNC_GROUP_SEARCH_BASE=" + groupSearchBase);
installProps.println("SYNC_LDAP_GROUP_SEARCH_FILTER=" + groupSearchFilter);
ambariProps.println("ranger.usersync.group.searchbase=" + groupSearchBase);
ambariProps.println("ranger.usersync.group.searchfilter=" + groupSearchFilter);
} finally {
if (groupSearchResultEnum != null) {
groupSearchResultEnum.close();
}
}
}
private List<SearchResult> ldapApiQuery(String name, String filter) {
String action = "query";
String logMsg = action + " " + filter;
List<SearchResult> result = new ArrayList<SearchResult>();
try {
initLdapContext(action);
LdapContext ldapCtx = ldapContexts.get(action);
SearchControls constraints = new SearchControls();
constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> en = ldapCtx.search(name, filter, constraints);
// means all nodes
if (en == null) {
loggerInfo("LDAP信息", "获取", "结果为空", logMsg);
return Collections.emptyList();
}
if (!en.hasMoreElements()) {
loggerInfo("LDAP信息", "获取", "结果为空", logMsg);
return Collections.emptyList();
}
while (en != null && en.hasMoreElements()) {// maybe more than one element
Object obj = en.nextElement();
if (obj instanceof SearchResult) {
SearchResult si = (SearchResult) obj;
result.add(si);
}
}
}
catch (Exception e) {
loggerError("LDAP用户信息获取", logMsg, e);
clearLdapContext(action);
}
if (!result.isEmpty()) {
loggerInfo("LDAP信息", "获取", "成功", logMsg);
}
return result;
}
boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
final LdapContextFactory ldapContextFactory) throws NamingException {
// ldap://host:port/dn?attributes?scope?filter?extensions
boolean member = false;
if (memberUrl == null) {
return false;
}
String[] tokens = memberUrl.split("\\?");
if (tokens.length < 4) {
return false;
}
String searchBaseString = tokens[0]
.substring(tokens[0].lastIndexOf('/') + 1);
String searchScope = tokens[2];
String searchFilter = tokens[3];
LdapName searchBaseDn = new LdapName(searchBaseString);
// do scope test
if ("base".equalsIgnoreCase(searchScope)) {
return false;
}
if (!userLdapDn.toString().endsWith(searchBaseDn.toString())) {
return false;
}
if ("one".equalsIgnoreCase(searchScope)
&& (userLdapDn.size() != searchBaseDn.size() - 1)) {
return false;
}
// search for the filter, substituting base with userDn
// search for base_dn=userDn, scope=base, filter=filter
LdapContext systemLdapCtx;
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
NamingEnumeration<SearchResult> searchResultEnum = null;
try {
searchResultEnum = systemLdapCtx
.search(userLdapDn, searchFilter,
"sub".equalsIgnoreCase(searchScope) ? SUBTREE_SCOPE
: ONELEVEL_SCOPE);
if (searchResultEnum.hasMore()) {
return true;
}
}
finally {
try {
if (searchResultEnum != null) {
searchResultEnum.close();
}
}
finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
return member;
}
@Override
public boolean hasRole(final String username, final String attribute) {
final String key = username + "_attr_" + attribute;
final long now = System.currentTimeMillis();
try {
if (!matchedExpired(key, now)) {
return true;
}
if (!unMatchedExpired(key, now)) {
return false;
}
// query AD to update both MapS and expiration time
LOGGER.fine("username: " + username + "; role: " + attribute);
this.writeLock.lock();
try {
// remove from cache if exists
this.matchedList.remove(key);
this.unMatchedList.remove(key);
int count = 0;
final LdapContext context = new InitialLdapContext(environment, null);
for (String filter : this.policy) {
// perform AD lookup add to cache
final NamingEnumeration<SearchResult> results =
context.search(this.deecee
, String.format(filter, username, attribute)
, this.srchCntrls);
final boolean found = results.hasMoreElements();
results.close();
// add to cache
if (found) {
count++;
//LOGGER.info("add attribute to matchedList: " + attribute);
this.matchedList.put(key, System.currentTimeMillis());
if (!this.uniqueOnly) {
break;
}
}
// check if we have a duplicate attribute
if (count > 1 && this.uniqueOnly) {
this.matchedList.remove(key);
throw new IllegalArgumentException("Uniqueness property violated. "
+ "Found duplicate role/attribute:" + attribute
+ ". This MAY be caused by an improper policy definition"
+ "; filter=" + filter
+ "; policy=" + this.policy);
}
}
context.close();
if (0 == count) {
//LOGGER.info("add attribute to unMatchedList: " + attribute);
this.unMatchedList.put(key, System.currentTimeMillis());
} else {
cacheUserInfo(username);
}
} finally {
this.writeLock.unlock();
}
} catch (NamingException lex) {
LOGGER.severe(lex.getMessage());
throw new RuntimeException(lex);
}
return hasRole(username, attribute);
}
@Override
public List<LdapUser> searchUsers(final String username, final LdapContext context, Long domainId) throws NamingException, IOException {
final SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(_ldapConfiguration.getScope());
searchControls.setReturningAttributes(_ldapConfiguration.getReturnAttributes(domainId));
String basedn = _ldapConfiguration.getBaseDn(domainId);
if (StringUtils.isBlank(basedn)) {
throw new IllegalArgumentException(String.format("ldap basedn is not configured (for domain: %s)", domainId));
}
byte[] cookie = null;
int pageSize = _ldapConfiguration.getLdapPageSize(domainId);
context.setRequestControls(new Control[]{new PagedResultsControl(pageSize, Control.NONCRITICAL)});
final List<LdapUser> users = new ArrayList<LdapUser>();
NamingEnumeration<SearchResult> results;
do {
results = context.search(basedn, generateSearchFilter(username, domainId), searchControls);
while (results.hasMoreElements()) {
final SearchResult result = results.nextElement();
if (!isUserDisabled(result)) {
users.add(createUser(result, domainId));
}
}
Control[] contextControls = context.getResponseControls();
if (contextControls != null) {
for (Control control : contextControls) {
if (control instanceof PagedResultsResponseControl) {
PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
cookie = prrc.getCookie();
}
}
} else {
LOGGER.info("No controls were sent from the ldap server");
}
context.setRequestControls(new Control[] {new PagedResultsControl(pageSize, cookie, Control.CRITICAL)});
} while (cookie != null);
return users;
}
@Override
protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException {
final GreenStepBaseUsernamePasswordToken usernamePasswordToken = (GreenStepBaseUsernamePasswordToken) token;
LdapContext ctx = null;
/*
try {
ctx = ldapContextFactory.getSystemLdapContext();
final String attribName = "userPrincipalName";
final SearchControls searchControls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, new String[] { attribName }, false, false);
final NamingEnumeration<SearchResult> search = ctx.search(searchBase, this.getCustomQueryAttributeValue(), new Object[] { usernamePasswordToken.getPrincipal() }, searchControls);
if (search.hasMore()) {
final SearchResult next = search.next();
String loginUser= next.getAttributes().get(attribName).get().toString();
if (search.hasMore()) {
throw new RuntimeException("More than one user matching: "+usernamePasswordToken.getPrincipal());
} else {
try {
ldapContextFactory.getLdapContext(loginUser, usernamePasswordToken.getPassword());
} catch (Exception ex) {
throw ex;
}
}
}
else {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
} catch (NamingException ne) {
throw ne;
} finally {
LdapUtils.closeContext(ctx);
}
*/
String searchBaseArr[] = StringUtils.defaultString(searchBase).split( Constants.ID_DELIMITER );
boolean searchUser = false;
for (int i = 0; searchBaseArr != null && !searchUser && i<searchBaseArr.length; i++) {
try {
ctx = ldapContextFactory.getSystemLdapContext();
final String attribName = "userPrincipalName";
final SearchControls searchControls = new SearchControls(SearchControls.SUBTREE_SCOPE, 1, 0, new String[] { attribName }, false, false);
final NamingEnumeration<SearchResult> search = ctx.search(searchBaseArr[i], this.getCustomQueryAttributeValue(), new Object[] { usernamePasswordToken.getPrincipal() }, searchControls);
if (search.hasMore()) {
searchUser = true;
final SearchResult next = search.next();
String loginUser= next.getAttributes().get(attribName).get().toString();
if (search.hasMore()) {
throw new RuntimeException("More than one user matching: "+usernamePasswordToken.getPrincipal());
} else {
try {
ldapContextFactory.getLdapContext(loginUser, usernamePasswordToken.getPassword());
} catch (Exception ex) {
throw ex;
}
}
}
/*
else {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
*/
} catch (NamingException ne) {
throw ne;
} finally {
LdapUtils.closeContext(ctx);
}
}
if (!searchUser) {
throw new RuntimeException("No user matching: " + usernamePasswordToken.getPrincipal());
}
return buildAuthenticationInfo(usernamePasswordToken.getUsername(), usernamePasswordToken.getPassword());
}
public void getAllGroups(LdapContext ldapContext) throws Throwable {
int noOfGroups = 0;
Attribute groupNameAttr;
Attribute groupMemberAttr;
NamingEnumeration<SearchResult> groupSearchResultEnum = null;
SearchControls groupSearchControls = new SearchControls();
groupSearchControls.setSearchScope(config.getGroupSearchScope());
Set<String> groupSearchAttributes = new HashSet<>();
groupSearchAttributes.add(groupNameAttrName);
groupSearchAttributes.add(groupMemberName);
groupSearchAttributes.add("distinguishedName");
groupSearchControls.setReturningAttributes(groupSearchAttributes.toArray(
new String[groupSearchAttributes.size()]));
String extendedGroupSearchFilter= "(objectclass=" + groupObjClassName + ")";
if (groupSearchFilter != null && !groupSearchFilter.trim().isEmpty()) {
String customFilter = groupSearchFilter.trim();
if (!customFilter.startsWith("(")) {
customFilter = "(" + customFilter + ")";
}
extendedGroupSearchFilter = "(&" + extendedGroupSearchFilter + customFilter + ")";
}
try {
groupSearchResultEnum = ldapContext.search(groupSearchBase, extendedGroupSearchFilter,
groupSearchControls);
logFile.println("\nINFO: First 20 Groups and associated Users are:");
while (groupSearchResultEnum.hasMore()) {
final SearchResult groupEntry = groupSearchResultEnum.next();
if (groupEntry == null) {
continue;
}
Attributes groupAttributes = groupEntry.getAttributes();
if (groupAttributes == null) {
logFile.println("WARN: Attributes missing for entry " + groupEntry.getNameInNamespace());
continue;
}
groupMemberAttr = groupAttributes.get(groupMemberName);
Set<String> users = new HashSet<>();
if (groupMemberAttr != null) {
NamingEnumeration<?> userEnum = groupMemberAttr.getAll();
while (userEnum.hasMore()) {
String userRes = userEnum.next().toString();
users.add(userRes);
}
}
groupNameAttr = groupAttributes.get(groupNameAttrName);
if (noOfGroups < 20) {
logFile.println("Group name: " + groupNameAttr.get().toString() + ", Users: " + users);
}
noOfGroups++;
}
logFile.println("\nINFO: Total no. of groups = " + noOfGroups);
} catch (NamingException ne) {
String msg = "Exception occured while retreiving groups\n";
if ((config.getGroupNameAttribute() != null && !config.getGroupNameAttribute().isEmpty()) ||
(config.getGroupObjectClass() != null && !config.getGroupObjectClass().isEmpty()) ||
(config.getUserGroupMemberAttributeName() != null && !config.getUserGroupMemberAttributeName().isEmpty()) ||
(config.getGroupSearchBase() != null && !config.getGroupSearchBase().isEmpty()) ||
(config.getGroupSearchFilter() != null && !config.getGroupSearchFilter().isEmpty())) {
throw new Exception("Please verify values for:\n ranger.usersync.group.memberattributename\n " +
"ranger.usersync.group.nameattribute\n" +
"ranger.usersync.group.objectclass\n" +
"ranger.usersync.group.searchbase\n" +
"ranger.usersync.group.searchfilter\n");
} else {
throw new Exception(msg + ne);
}
} finally {
if (groupSearchResultEnum != null) {
groupSearchResultEnum.close();
}
}
}
/**
* Generic routine for retrieving a single element from the LDAP server. It's meant to be very
* flexible so that just about any query for a single results can make use of it without having
* to reimplement their own calls to LDAP.
* <p>
* The passed in filter string needs to be pre-prepared! In other words, nothing will be changed
* in the string before it is used as a string.
*
* @param attribute LDAP attribute to be pulled from each result and placed in the return results.
* Typically pulled from this manager. Null means the the absolute DN is returned.
* @param searchFilter Filter to use to perform the search. Typically pulled from this manager.
* @param failOnMultipleResults It true, an {@link IllegalStateException} will be thrown, if the
* search result is not unique. If false, just the first result will be returned.
* @param baseDN DN where to start the search. Typically {@link #getBaseDN()} or {@link #getAlternateBaseDN()}.
* @return A single string.
*/
public String retrieveSingle(String attribute, String searchFilter, boolean failOnMultipleResults, LdapName baseDN) {
LdapContext ctx = null;
try {
ctx = getContext(baseDN);
SearchControls searchControls = new SearchControls();
// See if recursive searching is enabled. Otherwise, only search one level.
if (isSubTreeSearch()) {
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
}
else {
searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
}
searchControls.setReturningAttributes(attribute == null ? new String[0] : new String[]{attribute});
NamingEnumeration<SearchResult> answer = ctx.search("", searchFilter, searchControls);
if (answer == null || !answer.hasMoreElements()) {
return null;
}
SearchResult searchResult = answer.next();
String result = attribute == null
? new LdapName(searchResult.getName()).addAll(0, baseDN).toString() :
(String) searchResult.getAttributes().get(attribute).get();
if (answer.hasMoreElements()) {
Log.debug("Search result for '{}' is not unique.", searchFilter);
if (failOnMultipleResults)
throw new IllegalStateException("Search result for " + searchFilter + " is not unique.");
}
answer.close();
return result;
}
catch (Exception e) {
Log.error("Error while searching for single result of: {}", searchFilter, e);
return null;
}
finally {
try {
if (ctx != null) {
ctx.close();
}
} catch (Exception ex) {
Log.debug("An exception occurred while trying to close a LDAP context after trying to retrieve a single attribute element for {}.", attribute, ex);
}
}
}
boolean isUserMemberOfDynamicGroup(LdapName userLdapDn, String memberUrl,
final LdapContextFactory ldapContextFactory) throws NamingException {
// ldap://host:port/dn?attributes?scope?filter?extensions
if (memberUrl == null) {
return false;
}
String[] tokens = memberUrl.split("\\?");
if (tokens.length < 4) {
return false;
}
String searchBaseString = tokens[0].substring(tokens[0].lastIndexOf("/") + 1);
String searchScope = tokens[2];
String searchFilter = tokens[3];
LdapName searchBaseDn = new LdapName(searchBaseString);
// do scope test
if ("base".equalsIgnoreCase(searchScope)) {
log.debug("DynamicGroup SearchScope base");
return false;
}
if (!userLdapDn.toString().endsWith(searchBaseDn.toString())) {
return false;
}
if ("one".equalsIgnoreCase(searchScope) && (userLdapDn.size() != searchBaseDn.size() - 1)) {
log.debug("DynamicGroup SearchScope one");
return false;
}
// search for the filter, substituting base with userDn
// search for base_dn=userDn, scope=base, filter=filter
LdapContext systemLdapCtx = null;
systemLdapCtx = ldapContextFactory.getSystemLdapContext();
boolean member = false;
NamingEnumeration<SearchResult> searchResultEnum = null;
try {
searchResultEnum = systemLdapCtx.search(userLdapDn, searchFilter,
"sub".equalsIgnoreCase(searchScope) ? SUBTREE_SCOPE : ONELEVEL_SCOPE);
if (searchResultEnum.hasMore()) {
return true;
}
} finally {
try {
if (searchResultEnum != null) {
searchResultEnum.close();
}
} finally {
LdapUtils.closeContext(systemLdapCtx);
}
}
return member;
}