001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020 package org.apache.directory.server.kerberos.shared.store.operations; 021 022 import org.apache.directory.server.core.CoreSession; 023 import org.apache.directory.server.core.filtering.EntryFilteringCursor; 024 import org.apache.directory.server.i18n.I18n; 025 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType; 026 import org.apache.directory.server.kerberos.shared.io.encoder.EncryptionKeyEncoder; 027 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey; 028 import org.apache.directory.server.kerberos.shared.store.KerberosAttribute; 029 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry; 030 import org.apache.directory.shared.ldap.constants.SchemaConstants; 031 import org.apache.directory.shared.ldap.entry.StringValue; 032 import org.apache.directory.shared.ldap.entry.ServerEntry; 033 import org.apache.directory.shared.ldap.entry.Value; 034 import org.apache.directory.shared.ldap.filter.EqualityNode; 035 import org.apache.directory.shared.ldap.filter.ExprNode; 036 import org.apache.directory.shared.ldap.filter.SearchScope; 037 import org.apache.directory.shared.ldap.message.AliasDerefMode; 038 import org.apache.directory.shared.ldap.name.DN; 039 import org.apache.directory.shared.ldap.schema.AttributeType; 040 import org.apache.directory.shared.ldap.schema.SchemaManager; 041 import org.slf4j.Logger; 042 import org.slf4j.LoggerFactory; 043 044 045 /** 046 * Commonly used store utility operations. 047 * 048 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 049 * @version $Rev$, $Date$ 050 */ 051 public class StoreUtils 052 { 053 private static final Logger LOG = LoggerFactory.getLogger( StoreUtils.class ); 054 055 056 /** 057 * Creates a ServerEntry for a PrincipalStoreEntry, doing what a state 058 * factory does but for ServerEntry instead of Attributes. 059 * 060 * @param session the session to use to access the directory's registries 061 * @param dn the distinguished name of the principal to be 062 * @param principalEntry the principal entry to convert into a ServerEntry 063 * @return the resultant server entry for the PrincipalStoreEntry argument 064 * @throws Exception if there are problems accessing registries 065 */ 066 public static ServerEntry toServerEntry( CoreSession session, DN dn, PrincipalStoreEntry principalEntry ) 067 throws Exception 068 { 069 ServerEntry outAttrs = session.getDirectoryService().newEntry( dn ); 070 071 // process the objectClass attribute 072 outAttrs.add( SchemaConstants.OBJECT_CLASS_AT, 073 SchemaConstants.TOP_OC, SchemaConstants.UID_OBJECT_AT, 074 "uidObject", SchemaConstants.EXTENSIBLE_OBJECT_OC, 075 SchemaConstants.PERSON_OC, SchemaConstants.ORGANIZATIONAL_PERSON_OC, 076 SchemaConstants.INET_ORG_PERSON_OC, SchemaConstants.KRB5_PRINCIPAL_OC, 077 "krb5KDCEntry" ); 078 079 outAttrs.add( SchemaConstants.UID_AT, principalEntry.getUserId() ); 080 outAttrs.add( KerberosAttribute.APACHE_SAM_TYPE_AT, "7" ); 081 outAttrs.add( SchemaConstants.SN_AT, principalEntry.getUserId() ); 082 outAttrs.add( SchemaConstants.CN_AT, principalEntry.getCommonName() ); 083 084 EncryptionKey encryptionKey = principalEntry.getKeyMap().get( EncryptionType.DES_CBC_MD5 ); 085 outAttrs.add( KerberosAttribute.KRB5_KEY_AT, EncryptionKeyEncoder.encode( encryptionKey ) ); 086 087 int keyVersion = encryptionKey.getKeyVersion(); 088 089 outAttrs.add( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principalEntry.getPrincipal().getName() ); 090 outAttrs.add( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, Integer.toString( keyVersion ) ); 091 092 return outAttrs; 093 } 094 095 096 /** 097 * Constructs a filter expression tree for the filter used to search the 098 * directory. 099 * 100 * @param registry the registry to use for attribute lookups 101 * @param principal the principal to use for building the filter 102 * @return the filter expression tree 103 * @throws Exception if there are problems while looking up attributes 104 */ 105 private static ExprNode getFilter( SchemaManager schemaManager, String principal ) throws Exception 106 { 107 AttributeType type = schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ); 108 Value<String> value = new StringValue( type, principal ); 109 return new EqualityNode<String>( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, value ); 110 } 111 112 113 /** 114 * Finds the ServerEntry associated with the Kerberos principal name. 115 * 116 * @param session the session to use for the search 117 * @param searchBaseDn the base to use while searching 118 * @param principal the name of the principal to search for 119 * @return the server entry for the principal or null if non-existent 120 * @throws Exception if there are problems while searching the directory 121 */ 122 public static ServerEntry findPrincipalEntry( CoreSession session, DN searchBaseDn, String principal ) 123 throws Exception 124 { 125 EntryFilteringCursor cursor = null; 126 127 try 128 { 129 SchemaManager schemaManager = session.getDirectoryService().getSchemaManager(); 130 cursor = session.search( searchBaseDn, SearchScope.SUBTREE, 131 getFilter( schemaManager, principal ), AliasDerefMode.DEREF_ALWAYS, null ); 132 133 cursor.beforeFirst(); 134 if ( cursor.next() ) 135 { 136 ServerEntry entry = cursor.get(); 137 LOG.debug( "Found entry {} for kerberos principal name {}", entry, principal ); 138 139 while ( cursor.next() ) 140 { 141 LOG.error( I18n.err( I18n.ERR_149, principal, cursor.next() ) ); 142 } 143 144 return entry; 145 } 146 else 147 { 148 LOG.warn( "No server entry found for kerberos principal name {}", principal ); 149 return null; 150 } 151 } 152 finally 153 { 154 if ( cursor != null ) 155 { 156 cursor.close(); 157 } 158 } 159 } 160 }