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.kerberos.shared.store.operations;
21  
22  import org.apache.directory.server.core.CoreSession;
23  import org.apache.directory.server.core.entry.ServerEntry;
24  import org.apache.directory.server.core.entry.ServerStringValue;
25  import org.apache.directory.server.core.filtering.EntryFilteringCursor;
26  import org.apache.directory.server.kerberos.shared.crypto.encryption.EncryptionType;
27  import org.apache.directory.server.kerberos.shared.io.encoder.EncryptionKeyEncoder;
28  import org.apache.directory.server.kerberos.shared.messages.value.EncryptionKey;
29  import org.apache.directory.server.kerberos.shared.store.KerberosAttribute;
30  import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
31  import org.apache.directory.server.schema.registries.AttributeTypeRegistry;
32  import org.apache.directory.shared.ldap.constants.SchemaConstants;
33  import org.apache.directory.shared.ldap.entry.Value;
34  import org.apache.directory.shared.ldap.filter.EqualityNode;
35  import org.apache.directory.shared.ldap.filter.ExprNode;
36  import org.apache.directory.shared.ldap.filter.SearchScope;
37  import org.apache.directory.shared.ldap.message.AliasDerefMode;
38  import org.apache.directory.shared.ldap.name.LdapDN;
39  import org.apache.directory.shared.ldap.schema.AttributeType;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  
43  
44  /**
45   * Commonly used store utility operations.
46   *
47   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
48   * @version $Rev$, $Date$
49   */
50  public class StoreUtils
51  {
52      private static final Logger LOG = LoggerFactory.getLogger( StoreUtils.class );
53      
54      
55      /**
56       * Creates a ServerEntry for a PrincipalStoreEntry, doing what a state 
57       * factory does but for ServerEntry instead of Attributes.
58       *
59       * @param session the session to use to access the directory's registries
60       * @param dn the distinguished name of the principal to be 
61       * @param principalEntry the principal entry to convert into a ServerEntry
62       * @return the resultant server entry for the PrincipalStoreEntry argument
63       * @throws Exception if there are problems accessing registries
64       */
65      public static ServerEntry toServerEntry( CoreSession session, LdapDN dn, PrincipalStoreEntry principalEntry ) 
66          throws Exception
67      {
68          ServerEntry outAttrs = session.getDirectoryService().newEntry( dn );
69          
70          // process the objectClass attribute
71          outAttrs.add( SchemaConstants.OBJECT_CLASS_AT, 
72              SchemaConstants.TOP_OC, SchemaConstants.UID_OBJECT_AT, 
73              "uidObject", SchemaConstants.EXTENSIBLE_OBJECT_OC, 
74              SchemaConstants.PERSON_OC, SchemaConstants.ORGANIZATIONAL_PERSON_OC,
75              SchemaConstants.INET_ORG_PERSON_OC, SchemaConstants.KRB5_PRINCIPAL_OC,
76              "krb5KDCEntry" );
77  
78          outAttrs.add( SchemaConstants.UID_AT, principalEntry.getUserId() );
79          outAttrs.add( KerberosAttribute.APACHE_SAM_TYPE_AT, "7" );
80          outAttrs.add( SchemaConstants.SN_AT, principalEntry.getUserId() );
81          outAttrs.add( SchemaConstants.CN_AT, principalEntry.getCommonName() );
82          
83          EncryptionKey encryptionKey = principalEntry.getKeyMap().get( EncryptionType.DES_CBC_MD5 );
84          outAttrs.add( KerberosAttribute.KRB5_KEY_AT, EncryptionKeyEncoder.encode( encryptionKey ) );
85  
86          int keyVersion = encryptionKey.getKeyVersion();
87  
88          outAttrs.add( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT, principalEntry.getPrincipal().getName() );
89          outAttrs.add( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT, Integer.toString( keyVersion ) );
90  
91          return outAttrs;
92      }
93      
94      
95      /**
96       * Constructs a filter expression tree for the filter used to search the 
97       * directory.
98       * 
99       * @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( "krb5Principal" );
107         Value<String> value = new ServerStringValue( type, principal );
108         return new EqualityNode<String>( "krb5Principal", 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 }