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 */
020package org.apache.directory.server.protocol.shared.kerberos;
021
022
023import java.text.ParseException;
024import java.util.Map;
025
026import javax.security.auth.kerberos.KerberosPrincipal;
027
028import org.apache.directory.server.core.api.CoreSession;
029import org.apache.directory.server.i18n.I18n;
030import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntry;
031import org.apache.directory.server.kerberos.shared.store.PrincipalStoreEntryModifier;
032import org.apache.directory.shared.kerberos.KerberosAttribute;
033import org.apache.directory.shared.kerberos.KerberosTime;
034import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
035import org.apache.directory.shared.kerberos.codec.types.PrincipalNameType;
036import org.apache.directory.shared.kerberos.codec.types.SamType;
037import org.apache.directory.shared.kerberos.components.EncryptionKey;
038import org.apache.directory.shared.kerberos.exceptions.KerberosException;
039import org.apache.directory.api.ldap.model.entry.Attribute;
040import org.apache.directory.api.ldap.model.entry.Entry;
041import org.apache.directory.api.ldap.model.exception.LdapException;
042import org.apache.directory.api.ldap.model.exception.LdapInvalidAttributeValueException;
043import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
044import org.apache.directory.api.ldap.model.name.Dn;
045
046
047/**
048 * Encapsulates the action of looking up a principal in an embedded ApacheDS DIT.
049 *
050 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
051 */
052public class GetPrincipal
053{
054    /** The name of the principal to get. */
055    private final KerberosPrincipal principal;
056
057
058    /**
059     * Creates the action to be used against the embedded ApacheDS DIT.
060     * 
061     * @param principal The principal to search for in the directory.
062     */
063    public GetPrincipal( KerberosPrincipal principal )
064    {
065        this.principal = principal;
066    }
067
068
069    /**
070     * Note that the base is a relative path from the existing context.
071     * It is not a Dn.
072     * 
073     * @param session The Session
074     * @param base The principal's Dn
075     * @return The found entry
076     * @throws Exception If the execution failed
077     */
078    public Object execute( CoreSession session, Dn base ) throws Exception
079    {
080        if ( principal == null )
081        {
082            return null;
083        }
084
085        Entry entry = StoreUtils.findPrincipalEntry( session, base, principal.getName() );
086        
087        if ( entry == null )
088        {
089            return null;
090        }
091        else
092        {
093            return getEntry( entry );
094        }
095    }
096
097
098    /**
099     * Marshals an a PrincipalStoreEntry from an Attributes object.
100     *
101     * @param dn the distinguished name of the Kerberos principal
102     * @param attrs the attributes of the Kerberos principal
103     * @return the entry for the principal
104     * @throws LdapException if there are any access problems
105     */
106    private PrincipalStoreEntry getEntry( Entry entry ) throws LdapException
107    {
108        PrincipalStoreEntryModifier modifier = new PrincipalStoreEntryModifier();
109
110        modifier.setDistinguishedName( entry.getDn().getName() );
111
112        String principalname = entry.get( KerberosAttribute.KRB5_PRINCIPAL_NAME_AT ).getString();
113        modifier.setPrincipal( new KerberosPrincipal( principalname, PrincipalNameType.KRB_NT_PRINCIPAL.getValue() ) );
114
115        String keyVersionNumber = entry.get( KerberosAttribute.KRB5_KEY_VERSION_NUMBER_AT ).getString();
116        modifier.setKeyVersionNumber( Integer.parseInt( keyVersionNumber ) );
117
118        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ) != null )
119        {
120            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_DISABLED_AT ).getString();
121            modifier.setDisabled( "true".equalsIgnoreCase( val ) );
122        }
123
124        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ) != null )
125        {
126            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_LOCKEDOUT_AT ).getString();
127            modifier.setLockedOut( "true".equalsIgnoreCase( val ) );
128        }
129
130        if ( entry.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ) != null )
131        {
132            String val = entry.get( KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT ).getString();
133            try
134            {
135                modifier.setExpiration( KerberosTime.getTime( val ) );
136            }
137            catch ( ParseException e )
138            {
139                throw new LdapInvalidAttributeValueException( ResultCodeEnum.OPERATIONS_ERROR,
140                    "Account expiration attribute "
141                    + KerberosAttribute.KRB5_ACCOUNT_EXPIRATION_TIME_AT 
142                    + " contained an invalid value for generalizedTime: "
143                    + val );
144            }
145        }
146
147        if ( entry.get( KerberosAttribute.APACHE_SAM_TYPE_AT ) != null )
148        {
149            String samType = entry.get( KerberosAttribute.APACHE_SAM_TYPE_AT ).getString();
150            modifier.setSamType( SamType.getTypeByOrdinal( Integer.parseInt( samType ) ) );
151        }
152
153        if ( entry.get( KerberosAttribute.KRB5_KEY_AT ) != null )
154        {
155            Attribute krb5key = entry.get( KerberosAttribute.KRB5_KEY_AT );
156            
157            try
158            {
159                Map<EncryptionType, EncryptionKey> keyMap = modifier.reconstituteKeyMap( krb5key );
160                modifier.setKeyMap( keyMap );
161            }
162            catch ( KerberosException ioe )
163            {
164                throw new LdapInvalidAttributeValueException( ResultCodeEnum.OPERATIONS_ERROR, 
165                    I18n.err( I18n.ERR_623, KerberosAttribute.KRB5_KEY_AT ), ioe );
166            }
167        }
168
169        return modifier.getEntry();
170    }
171}