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.entry.ServerEntry;
024 import org.apache.directory.server.core.entry.ServerStringValue;
025 import org.apache.directory.server.core.filtering.EntryFilteringCursor;
026 import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
027 import org.apache.directory.server.kerberos.shared.io.encoder.EncryptionKeyEncoder;
028 import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
029 import org.apache.directory.server.kerberos.shared.store.KerberosAttribute;
030 import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
031 import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
032 import org.apache.directory.shared.ldap.constants.SchemaConstants;
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.LdapDN;
039 import org.apache.directory.shared.ldap.schema.AttributeType;
040 import org.slf4j.Logger;
041 import org.slf4j.LoggerFactory;
042
043
044 /**
045 * Commonly used store utility operations.
046 *
047 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
048 * @version $Rev$, $Date$
049 */
050 public class StoreUtils
051 {
052 private static final Logger LOG = LoggerFactory.getLogger( StoreUtils.class );
053
054
055 /**
056 * Creates a ServerEntry for a PrincipalStoreEntry, doing what a state
057 * factory does but for ServerEntry instead of Attributes.
058 *
059 * @param session the session to use to access the directory's registries
060 * @param dn the distinguished name of the principal to be
061 * @param principalEntry the principal entry to convert into a ServerEntry
062 * @return the resultant server entry for the PrincipalStoreEntry argument
063 * @throws Exception if there are problems accessing registries
064 */
065 public static ServerEntry toServerEntry( CoreSession session, LdapDN dn, PrincipalStoreEntry principalEntry )
066 throws Exception
067 {
068 ServerEntry outAttrs = session.getDirectoryService().newEntry( dn );
069
070 // process the objectClass attribute
071 outAttrs.add( SchemaConstants.OBJECT_CLASS_AT,
072 SchemaConstants.TOP_OC, SchemaConstants.UID_OBJECT_AT,
073 "uidObject", SchemaConstants.EXTENSIBLE_OBJECT_OC,
074 SchemaConstants.PERSON_OC, SchemaConstants.ORGANIZATIONAL_PERSON_OC,
075 SchemaConstants.INET_ORG_PERSON_OC, SchemaConstants.KRB5_PRINCIPAL_OC,
076 "krb5KDCEntry" );
077
078 outAttrs.add( SchemaConstants.UID_AT, principalEntry.getUserId() );
079 outAttrs.add( KerberosAttribute.APACHE_SAM_TYPE_AT, "7" );
080 outAttrs.add( SchemaConstants.SN_AT, principalEntry.getUserId() );
081 outAttrs.add( SchemaConstants.CN_AT, principalEntry.getCommonName() );
082
083 EncryptionKey encryptionKey = principalEntry.getKeyMap().get( EncryptionType.DES_CBC_MD5 );
084 outAttrs.add( KerberosAttribute.KRB5_KEY_AT, EncryptionKeyEncoder.encode( encryptionKey ) );
085
086 int keyVersion = encryptionKey.getKeyVersion();
087
088 outAttrs.add( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principalEntry.getPrincipal().getName() );
089 outAttrs.add( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, Integer.toString( keyVersion ) );
090
091 return outAttrs;
092 }
093
094
095 /**
096 * Constructs a filter expression tree for the filter used to search the
097 * directory.
098 *
099 * @param registry the registry to use for attribute lookups
100 * @param principal the principal to use for building the filter
101 * @return the filter expression tree
102 * @throws Exception if there are problems while looking up attributes
103 */
104 private static ExprNode getFilter( AttributeTypeRegistry registry, String principal ) throws Exception
105 {
106 AttributeType type = registry.lookup( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT );
107 Value<String> value = new ServerStringValue( type, principal );
108 return new EqualityNode<String>( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, value );
109 }
110
111
112 /**
113 * Finds the ServerEntry associated with the Kerberos principal name.
114 *
115 * @param session the session to use for the search
116 * @param searchBaseDn the base to use while searching
117 * @param principal the name of the principal to search for
118 * @return the server entry for the principal or null if non-existent
119 * @throws Exception if there are problems while searching the directory
120 */
121 public static ServerEntry findPrincipalEntry( CoreSession session, LdapDN searchBaseDn, String principal )
122 throws Exception
123 {
124 EntryFilteringCursor cursor = null;
125
126 try
127 {
128 AttributeTypeRegistry registry = session.getDirectoryService().getRegistries().getAttributeTypeRegistry();
129 cursor = session.search( searchBaseDn, SearchScope.SUBTREE,
130 getFilter( registry, principal ), AliasDerefMode.DEREF_ALWAYS, null );
131
132 cursor.beforeFirst();
133 if ( cursor.next() )
134 {
135 ServerEntry entry = cursor.get();
136 LOG.debug( "Found entry {} for kerberos principal name {}", entry, principal );
137
138 while ( cursor.next() )
139 {
140 LOG.error( "More than one server entry found for kerberos principal name {}: ",
141 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 }