001package org.apache.archiva.redback.common.ldap; 002 003/* 004 * Licensed to the Apache Software Foundation (ASF) under one 005 * or more contributor license agreements. See the NOTICE file 006 * distributed with this work for additional information 007 * regarding copyright ownership. The ASF licenses this file 008 * to you under the Apache License, Version 2.0 (the 009 * "License"); you may not use this file except in compliance 010 * with the License. You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, 015 * software distributed under the License is distributed on an 016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 017 * KIND, either express or implied. See the License for the 018 * specific language governing permissions and limitations 019 * under the License. 020 */ 021 022import javax.naming.CompositeName; 023import javax.naming.InvalidNameException; 024import javax.naming.NamingEnumeration; 025import javax.naming.NamingException; 026import javax.naming.directory.Attribute; 027import javax.naming.directory.Attributes; 028import javax.naming.ldap.LdapName; 029import javax.naming.ldap.Rdn; 030 031/** 032 * 033 * 034 */ 035public final class LdapUtils 036{ 037 038 private static String[] FILTER_ESCAPE_TABLE = new String['\\' + 1]; 039 040 041 // Characters that must be escaped in a user filter 042 static { 043 044 // Filter encoding table ------------------------------------- 045 // fill with char itself 046 for (char c = 0; c < FILTER_ESCAPE_TABLE.length; c++) { 047 FILTER_ESCAPE_TABLE[c] = String.valueOf(c); 048 } 049 050 // escapes (RFC2254) 051 FILTER_ESCAPE_TABLE['*'] = "\\2a"; 052 FILTER_ESCAPE_TABLE['('] = "\\28"; 053 FILTER_ESCAPE_TABLE[')'] = "\\29"; 054 FILTER_ESCAPE_TABLE['\\'] = "\\5c"; 055 FILTER_ESCAPE_TABLE[0] = "\\00"; 056 } 057 058 059 private LdapUtils() 060 { 061 // no op 062 } 063 064 @SuppressWarnings("unchecked") 065 public static String getLabeledUriValue( Attributes attributes, String attrName, String label, 066 String attributeDescription ) 067 throws MappingException 068 { 069 if ( attrName == null ) 070 { 071 return null; 072 } 073 074 Attribute attribute = attributes.get( attrName ); 075 if ( attribute != null ) 076 { 077 NamingEnumeration attrs; 078 try 079 { 080 attrs = attribute.getAll(); 081 } 082 catch ( NamingException e ) 083 { 084 throw new MappingException( 085 "Failed to retrieve " + attributeDescription + " (attribute: \'" + attrName + "\').", e ); 086 } 087 088 while ( attrs.hasMoreElements() ) 089 { 090 Object value = attrs.nextElement(); 091 092 String val = String.valueOf( value ); 093 094 if ( val.endsWith( " " + label ) ) 095 { 096 return val.substring( 0, val.length() - ( label.length() + 1 ) ); 097 } 098 } 099 } 100 101 return null; 102 } 103 104 public static String getAttributeValue( Attributes attributes, String attrName, String attributeDescription ) 105 throws MappingException 106 { 107 if ( attrName == null ) 108 { 109 return null; 110 } 111 112 Attribute attribute = attributes.get( attrName ); 113 if ( attribute != null ) 114 { 115 try 116 { 117 Object value = attribute.get(); 118 119 return String.valueOf( value ); 120 } 121 catch ( NamingException e ) 122 { 123 throw new MappingException( 124 "Failed to retrieve " + attributeDescription + " (attribute: \'" + attrName + "\').", e ); 125 } 126 } 127 128 return null; 129 } 130 131 public static String getAttributeValueFromByteArray( Attributes attributes, String attrName, 132 String attributeDescription ) 133 throws MappingException 134 { 135 if ( attrName == null ) 136 { 137 return null; 138 } 139 140 Attribute attribute = attributes.get( attrName ); 141 if ( attribute != null ) 142 { 143 try 144 { 145 byte[] value = (byte[]) attribute.get(); 146 147 return new String( value ); 148 } 149 catch ( NamingException e ) 150 { 151 throw new MappingException( 152 "Failed to retrieve " + attributeDescription + " (attribute: \'" + attrName + "\').", e ); 153 } 154 } 155 156 return null; 157 } 158 159 /** 160 * Returns a LDAP name from a given RDN string. The <code>name</code> parameter must be a string 161 * representation of a composite name (as returned by ldapsearch result getName()) 162 * @param name The string of the RDN (may be escaped) 163 * @return The LdapName that corresponds to this string 164 * @throws InvalidNameException If the string cannot be parsed as LDAP name 165 */ 166 public static LdapName getLdapNameFromString(final String name) throws InvalidNameException 167 { 168 CompositeName coName = new CompositeName( name ); 169 LdapName ldapName = new LdapName( "" ); 170 ldapName.addAll( coName ); 171 return ldapName; 172 } 173 174 /** 175 * Returns the first RDN value that matches the given type. 176 * E.g. for the RDN ou=People,dc=test,dc=de, and type dc it will return 'test'. 177 * 178 * @param name the ldap name 179 * @param type the type of the RDN entry 180 * @return 181 */ 182 public static String findFirstRdnValue(LdapName name, String type) { 183 for ( Rdn rdn : name.getRdns() ) 184 { 185 if ( rdn.getType( ).equals( type ) ) 186 { 187 Object val = rdn.getValue( ); 188 if (val!=null) { 189 return val.toString( ); 190 } else { 191 return ""; 192 } 193 } 194 } 195 return ""; 196 } 197 198 /** 199 * Escape a value for use in a filter. 200 * This method is copied from the spring framework class org.springframework.security.ldap.authentication.LdapEncoder 201 * 202 * @param value the value to escape. 203 * @return a properly escaped representation of the supplied value. 204 */ 205 public static String encodeFilterValue(String value) { 206 207 if (value == null) { 208 return null; 209 } 210 211 // make buffer roomy 212 StringBuilder encodedValue = new StringBuilder(value.length() * 2); 213 214 int length = value.length(); 215 216 for (int i = 0; i < length; i++) { 217 218 char c = value.charAt(i); 219 220 if (c < FILTER_ESCAPE_TABLE.length) { 221 encodedValue.append(FILTER_ESCAPE_TABLE[c]); 222 } 223 else { 224 // default: add the char 225 encodedValue.append(c); 226 } 227 } 228 229 return encodedValue.toString(); 230 } 231}