View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.server.protocol.shared.kerberos;
21  
22  
23  import java.nio.ByteBuffer;
24  
25  import org.apache.directory.api.ldap.model.constants.Loggers;
26  import org.apache.directory.api.ldap.model.constants.SchemaConstants;
27  import org.apache.directory.api.ldap.model.cursor.Cursor;
28  import org.apache.directory.api.ldap.model.entry.Entry;
29  import org.apache.directory.api.ldap.model.entry.Value;
30  import org.apache.directory.api.ldap.model.filter.EqualityNode;
31  import org.apache.directory.api.ldap.model.filter.ExprNode;
32  import org.apache.directory.api.ldap.model.message.AliasDerefMode;
33  import org.apache.directory.api.ldap.model.message.SearchScope;
34  import org.apache.directory.api.ldap.model.name.Dn;
35  import org.apache.directory.api.ldap.model.schema.AttributeType;
36  import org.apache.directory.api.ldap.model.schema.SchemaManager;
37  import org.apache.directory.server.core.api.CoreSession;
38  import org.apache.directory.server.i18n.I18n;
39  import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
40  import org.apache.directory.shared.kerberos.KerberosAttribute;
41  import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
42  import org.apache.directory.shared.kerberos.components.EncryptionKey;
43  import org.slf4j.Logger;
44  import org.slf4j.LoggerFactory;
45  
46  
47  /**
48   * Commonly used store utility operations.
49   *
50   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
51   */
52  public final class StoreUtils
53  {
54      /** Loggers for this class */
55      private static final Logger LOG = LoggerFactory.getLogger( StoreUtils.class );
56      private static final Logger LOG_KRB = LoggerFactory.getLogger( Loggers.KERBEROS_LOG.getName() );
57  
58  
59      private StoreUtils()
60      {
61      }
62  
63  
64      /**
65       * Creates a Entry for a PrincipalStoreEntry, doing what a state 
66       * factory does but for Entry instead of Attributes.
67       *
68       * @param session the session to use to access the directory's registries
69       * @param dn the distinguished name of the principal to be 
70       * @param principalEntry the principal entry to convert into a Entry
71       * @return the resultant server entry for the PrincipalStoreEntry argument
72       * @throws Exception if there are problems accessing registries
73       */
74      public static Entry toServerEntry( CoreSession session, Dn dn, PrincipalStoreEntry principalEntry )
75          throws Exception
76      {
77          Entry outAttrs = session.getDirectoryService().newEntry( dn );
78  
79          // process the objectClass attribute
80          outAttrs.add( SchemaConstants.OBJECT_CLASS_AT,
81              SchemaConstants.TOP_OC, SchemaConstants.UID_OBJECT_AT,
82              "uidObject", SchemaConstants.EXTENSIBLE_OBJECT_OC,
83              SchemaConstants.PERSON_OC, SchemaConstants.ORGANIZATIONAL_PERSON_OC,
84              SchemaConstants.INET_ORG_PERSON_OC, SchemaConstants.KRB5_PRINCIPAL_OC,
85              "krb5KDCEntry" );
86  
87          outAttrs.add( SchemaConstants.UID_AT, principalEntry.getUserId() );
88          outAttrs.add( KerberosAttribute.APACHE_SAM_TYPE_AT, "7" );
89          outAttrs.add( SchemaConstants.SN_AT, principalEntry.getUserId() );
90          outAttrs.add( SchemaConstants.CN_AT, principalEntry.getCommonName() );
91  
92          EncryptionKey encryptionKey = principalEntry.getKeyMap().get( EncryptionType.DES_CBC_MD5 );
93  
94          ByteBuffer buffer = ByteBuffer.allocate( encryptionKey.computeLength() );
95          outAttrs.add( KerberosAttribute.KRB5_KEY_AT, encryptionKey.encode( buffer ).array() );
96  
97          int keyVersion = encryptionKey.getKeyVersion();
98  
99          outAttrs.add( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principalEntry.getPrincipal().toString() );
100         outAttrs.add( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, Integer.toString( keyVersion ) );
101 
102         return outAttrs;
103     }
104 
105 
106     /**
107      * Constructs a filter expression tree for the filter used to search the 
108      * directory.
109      * 
110      * @param schemaManager The server schemaManager to use for attribute lookups
111      * @param principal the principal to use for building the filter
112      * @return the filter expression tree
113      * @throws Exception if there are problems while looking up attributes
114      */
115     private static ExprNode getFilter( SchemaManager schemaManager, String principal ) throws Exception
116     {
117         AttributeType type = schemaManager.lookupAttributeTypeRegistry( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT );
118         Value value = new Value( type, principal );
119 
120         return new EqualityNode<String>( type, value );
121     }
122 
123 
124     /**
125      * Finds the Entry associated with the Kerberos principal name.
126      *
127      * @param session the session to use for the search
128      * @param searchBaseDn the base to use while searching
129      * @param principal the name of the principal to search for
130      * @return the server entry for the principal or null if non-existent
131      * @throws Exception if there are problems while searching the directory
132      */
133     public static Entry findPrincipalEntry( CoreSession session, Dn searchBaseDn, String principal )
134         throws Exception
135     {
136         Cursor<Entry> cursor = null;
137 
138         try
139         {
140             SchemaManager schemaManager = session.getDirectoryService().getSchemaManager();
141             cursor = session
142                 .search( searchBaseDn, SearchScope.SUBTREE,
143                     getFilter( schemaManager, principal ), AliasDerefMode.DEREF_ALWAYS,
144                     SchemaConstants.ALL_USER_ATTRIBUTES );
145 
146             cursor.beforeFirst();
147 
148             if ( cursor.next() )
149             {
150                 Entry entry = cursor.get();
151                 LOG.debug( "Found entry {} for kerberos principal name {}", entry.getDn(), principal );
152                 LOG_KRB.debug( "Found entry {} for kerberos principal name {}", entry.getDn(), principal );
153 
154                 while ( cursor.next() )
155                 {
156                     LOG.error( I18n.err( I18n.ERR_149, principal, cursor.next() ) );
157                 }
158 
159                 return entry;
160             }
161             else
162             {
163                 LOG.warn( "No server entry found for kerberos principal name {}", principal );
164                 LOG_KRB.warn( "No server entry found for kerberos principal name {}", principal );
165 
166                 return null;
167             }
168         }
169         finally
170         {
171             if ( cursor != null )
172             {
173                 cursor.close();
174             }
175         }
176     }
177 }