/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.ambari.server.security.authorization;
import java.util.regex.Pattern;
import javax.naming.Context;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import javax.naming.NamingException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ldap.core.DirContextAdapter;
import org.springframework.ldap.support.LdapUtils;
import com.google.common.base.Preconditions;
/**
* Provides utility methods for LDAP related functionality
*/
public class AmbariLdapUtils {
private static final Logger LOG = LoggerFactory.getLogger(AmbariLdapUtils.class);
/**
* Regexp to verify if user login name beside user contains domain information as well (User principal name format).
*/
private static final Pattern UPN_FORMAT = Pattern.compile(".+@\\w+(\\.\\w+)*");
/**
* Returns true if the given user name contains domain name as well (e.g. username@domain)
*
* @param loginName the login name to verify if it contains domain information.
* @return true if the given user name contains domain name as well; false otherwise
*/
public static boolean isUserPrincipalNameFormat(String loginName) {
return UPN_FORMAT.matcher(loginName).matches();
}
/**
* Determine that the full DN of an LDAP object is in/out of the base DN scope.
*
* @param adapter used for get the full dn from the ldap query response
* @param baseDn the base distinguished name
* @return true if the object is out of scope; false otherwise
*/
public static boolean isLdapObjectOutOfScopeFromBaseDn(DirContextAdapter adapter, String baseDn) {
boolean isOutOfScope = true;
try {
Name dn = adapter.getDn();
Preconditions.checkArgument(dn != null, "DN cannot be null in LDAP response object");
Name fullDn = getFullDn(dn, adapter);
Name base = LdapUtils.newLdapName(baseDn);
if (fullDn.startsWith(base)) {
isOutOfScope = false;
}
} catch (Exception e) {
LOG.error(e.getMessage());
}
return isOutOfScope;
}
/**
* Ensures the given distinguished name is an absolute value rather than a name relative to the context.
*
* @param dn a distinguished name
* @param context the context containing the base distinguished name
* @return the absolute distinguished name
*/
public static Name getFullDn(String dn, Context context) throws NamingException {
return getFullDn(LdapUtils.newLdapName(dn), context);
}
/**
* Ensures the given distinguished name is an absolute value rather than a name relative to the context.
*
* @param dn a distinguished name
* @param context the context containing the base distinguished name
* @return the absolute distinguished name
*/
public static Name getFullDn(Name dn, Context context) throws NamingException {
return getFullDn(LdapUtils.newLdapName(dn), LdapUtils.newLdapName(context.getNameInNamespace()));
}
/**
* Ensures the given distinguished name is an absolute value rather than a name relative to the context.
*
* @param dn a distinguished name
* @param baseDn the base distinguished name
* @return the absolute distinguished name
*/
public static Name getFullDn(Name dn, Name baseDn) {
if (dn.startsWith(baseDn)) {
return dn;
} else {
try {
//Copy the baseDN so we do not change the one that is passed in...
baseDn = LdapUtils.newLdapName(baseDn);
baseDn.addAll(dn);
} catch (InvalidNameException e) {
LOG.error(e.getMessage());
}
return baseDn;
}
}
}